11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: mntfunc.c,v 1.19.6.4 2005/01/31 12:22:20 armin Exp $ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Driver for Eicon DIVA Server ISDN cards. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Maint module 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2000-2003 Cytronics & Melware (info@melware.de) 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "platform.h" 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "di_defs.h" 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "divasync.h" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "debug_if.h" 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char *DRIVERRELEASE_MNT; 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR) 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG) 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void DIVA_DIDD_Read(void *, int); 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic dword notify_handle; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DESCRIPTOR DAdapter; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DESCRIPTOR MAdapter; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DESCRIPTOR MaintDescriptor = 30475be4d85a274d0961593db41cf85689db1d583cJoe Perches{ IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp }; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int diva_os_copy_to_user(void *os_handle, void __user *dst, 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const void *src, int length); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int diva_os_copy_from_user(void *os_handle, void *dst, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const void __user *src, int length); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void no_printf(unsigned char *x, ...) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dummy debug function */ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "debuglib.c" 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DIDD callback function 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 47475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic void *didd_callback(void *context, DESCRIPTOR *adapter, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int removal) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (adapter->type == IDI_DADAPTER) { 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_ERR(("cb: Change in DAdapter ? Oops ?.")); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (adapter->type == IDI_DIMAINT) { 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (removal) { 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DbgDeregister(); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&MAdapter, 0, sizeof(MAdapter)); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintf = no_printf; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&MAdapter, adapter, sizeof(MAdapter)); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintf = (DIVA_DI_PRINTF) MAdapter.request; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DbgRegister("MAINT", DRIVERRELEASE_MNT, DBG_DEFAULT); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((adapter->type > 0) && (adapter->type < 16)) { 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (removal) { 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_mnt_remove_xdi_adapter(adapter); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_mnt_add_xdi_adapter(adapter); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (NULL); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * connect to didd 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int DIVA_INIT_FUNCTION connect_didd(void) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int x = 0; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dadapter = 0; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IDI_SYNC_REQ req; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS]; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table)); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (x = 0; x < MAX_DESCRIPTORS; x++) { 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dadapter = 1; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter)); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.e.Req = 0; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.e.Rc = 90475be4d85a274d0961593db41cf85689db1d583cJoe Perches IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.info.callback = (void *)didd_callback; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.info.context = NULL; 93475be4d85a274d0961593db41cf85689db1d583cJoe Perches DAdapter.request((ENTITY *)&req); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (req.didd_notify.e.Rc != 0xff) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify_handle = req.didd_notify.info.handle; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register MAINT (me) */ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_add_adapter.e.Req = 0; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_add_adapter.e.Rc = 100475be4d85a274d0961593db41cf85689db1d583cJoe Perches IDI_SYNC_REQ_DIDD_ADD_ADAPTER; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_add_adapter.info.descriptor = 102475be4d85a274d0961593db41cf85689db1d583cJoe Perches (void *) &MaintDescriptor; 103475be4d85a274d0961593db41cf85689db1d583cJoe Perches DAdapter.request((ENTITY *)&req); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (req.didd_add_adapter.e.Rc != 0xff) 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((DIDD_Table[x].type > 0) 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (DIDD_Table[x].type < 16)) { 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_mnt_add_xdi_adapter(&DIDD_Table[x]); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (dadapter); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disconnect from didd 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void DIVA_EXIT_FUNCTION disconnect_didd(void) 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IDI_SYNC_REQ req; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.e.Req = 0; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_notify.info.handle = notify_handle; 124475be4d85a274d0961593db41cf85689db1d583cJoe Perches DAdapter.request((ENTITY *)&req); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_remove_adapter.e.Req = 0; 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_remove_adapter.info.p_request = 129475be4d85a274d0961593db41cf85689db1d583cJoe Perches (IDI_CALL) MaintDescriptor.request; 130475be4d85a274d0961593db41cf85689db1d583cJoe Perches DAdapter.request((ENTITY *)&req); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * read/write maint 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint maint_read_write(void __user *buf, int count) 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byte data[128]; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dword cmd, id, mask; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 0; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count < (3 * sizeof(dword))) 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EFAULT); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (diva_os_copy_from_user(NULL, (void *) &data[0], 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf, 3 * sizeof(dword))) { 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EFAULT); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 150475be4d85a274d0961593db41cf85689db1d583cJoe Perches cmd = *(dword *)&data[0]; /* command */ 151475be4d85a274d0961593db41cf85689db1d583cJoe Perches id = *(dword *)&data[4]; /* driver id */ 152475be4d85a274d0961593db41cf85689db1d583cJoe Perches mask = *(dword *)&data[8]; /* mask or size */ 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_CMD_GET_DRIVER_INFO: 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = diva_get_driver_info(id, data, sizeof(data))) > 0) { 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((count < ret) || diva_os_copy_to_user 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (NULL, buf, (void *) &data[0], ret)) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_READ_DRIVER_DBG_MASK: 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = diva_get_driver_dbg_mask(id, (byte *) data)) > 0) { 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((count < ret) || diva_os_copy_to_user 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (NULL, buf, (void *) &data[0], ret)) 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENODEV; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_WRITE_DRIVER_DBG_MASK: 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = diva_set_driver_dbg_mask(id, mask)) <= 0) { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENODEV; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* 182475be4d85a274d0961593db41cf85689db1d583cJoe Perches Filter commands will ignore the ID due to fact that filtering affects 183475be4d85a274d0961593db41cf85689db1d583cJoe Perches the B- channel and Audio Tap trace levels only. Also MAINT driver will 184475be4d85a274d0961593db41cf85689db1d583cJoe Perches select the right trace ID by itself 185475be4d85a274d0961593db41cf85689db1d583cJoe Perches */ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_WRITE_SELECTIVE_TRACE_FILTER: 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mask) { 188475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = diva_set_trace_filter(1, "*"); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (mask < sizeof(data)) { 190475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (diva_os_copy_from_user(NULL, data, (char __user *)buf + 12, mask)) { 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 193475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = diva_set_trace_filter((int)mask, data); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_READ_SELECTIVE_TRACE_FILTER: 201475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((ret = diva_get_trace_filter(sizeof(data), data)) > 0) { 202475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (diva_os_copy_to_user(NULL, buf, data, ret)) 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -ENODEV; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_READ_TRACE_ENTRY:{ 210475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_spin_lock_magic_t old_irql; 211475be4d85a274d0961593db41cf85689db1d583cJoe Perches word size; 212475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_dbg_entry_head_t *pmsg; 213475be4d85a274d0961593db41cf85689db1d583cJoe Perches byte *pbuf; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 215475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(pbuf = diva_os_malloc(0, mask))) { 216475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (-ENOMEM); 217475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 219475be4d85a274d0961593db41cf85689db1d583cJoe Perches for (;;) { 220475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(pmsg = 221475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_get_message(&size, &old_irql))) { 222475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 223475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 224475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (size > mask) { 225475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_ack_message(0, &old_irql); 226475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = -EINVAL; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 229475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = size; 230475be4d85a274d0961593db41cf85689db1d583cJoe Perches memcpy(pbuf, pmsg, size); 231475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_ack_message(1, &old_irql); 232475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((count < size) || 233475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_copy_to_user(NULL, buf, (void *) pbuf, size)) 234475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = -EFAULT; 235475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 237475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_free(0, pbuf); 238475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_READ_TRACE_ENTRYS:{ 242475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_spin_lock_magic_t old_irql; 243475be4d85a274d0961593db41cf85689db1d583cJoe Perches word size; 244475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_dbg_entry_head_t *pmsg; 245475be4d85a274d0961593db41cf85689db1d583cJoe Perches byte *pbuf = NULL; 246475be4d85a274d0961593db41cf85689db1d583cJoe Perches int written = 0; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 248475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (mask < 4096) { 249475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = -EINVAL; 250475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 251475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 252475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(pbuf = diva_os_malloc(0, mask))) { 253475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (-ENOMEM); 254475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 255475be4d85a274d0961593db41cf85689db1d583cJoe Perches 256475be4d85a274d0961593db41cf85689db1d583cJoe Perches for (;;) { 257475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(pmsg = 258475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_get_message(&size, &old_irql))) { 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 261475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((size + 8) > mask) { 262475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_ack_message(0, &old_irql); 263475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 265475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* 266475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write entry length 267475be4d85a274d0961593db41cf85689db1d583cJoe Perches */ 268475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = (byte) size; 269475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = (byte) (size >> 8); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 272475be4d85a274d0961593db41cf85689db1d583cJoe Perches /* 273475be4d85a274d0961593db41cf85689db1d583cJoe Perches Write message 274475be4d85a274d0961593db41cf85689db1d583cJoe Perches */ 275475be4d85a274d0961593db41cf85689db1d583cJoe Perches memcpy(&pbuf[written], pmsg, size); 276475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_maint_ack_message(1, &old_irql); 277475be4d85a274d0961593db41cf85689db1d583cJoe Perches written += size; 278475be4d85a274d0961593db41cf85689db1d583cJoe Perches mask -= (size + 4); 279475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 280475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = 0; 281475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = 0; 282475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = 0; 283475be4d85a274d0961593db41cf85689db1d583cJoe Perches pbuf[written++] = 0; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 285475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) { 286475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = -EFAULT; 287475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 288475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = written; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 290475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_free(0, pbuf); 291475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (ret); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * init 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer, 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long diva_dbg_mem) 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*buffer_length < 64) { 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buffer_length = 64; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*buffer_length > 512) { 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buffer_length = 512; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buffer_length *= 1024; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (diva_dbg_mem) { 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buffer = (void *) diva_dbg_mem; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((*buffer_length >= (64 * 1024)) 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && 319475be4d85a274d0961593db41cf85689db1d583cJoe Perches (!(*buffer = diva_os_malloc(0, *buffer_length)))) { 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *buffer_length -= 1024; 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!*buffer) { 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_ERR(("init: Can not alloc trace buffer")); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) { 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!diva_dbg_mem) { 331475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_free(0, *buffer); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_ERR(("init: maint init failed")); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!connect_didd()) { 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_ERR(("init: failed to connect to DIDD.")); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_finit(); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!diva_dbg_mem) { 341475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_free(0, *buffer); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * exit 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid DIVA_EXIT_FUNCTION mntfunc_finit(void) 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *buffer; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 100; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DbgDeregister(); 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (diva_mnt_shutdown_xdi_adapters() && i--) { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_sleep(10); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disconnect_didd(); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((buffer = diva_maint_finit())) { 365475be4d85a274d0961593db41cf85689db1d583cJoe Perches diva_os_free(0, buffer); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&MAdapter, 0, sizeof(MAdapter)); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintf = no_printf; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 371