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 = 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 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 */ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic 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 = 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 = 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IDI_SYNC_REQ_DIDD_ADD_ADAPTER; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds req.didd_add_adapter.info.descriptor = 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void *) &MaintDescriptor; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 = 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IDI_CALL) MaintDescriptor.request; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = *(dword *) & data[0]; /* command */ 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id = *(dword *) & data[4]; /* driver id */ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Filter commands will ignore the ID due to fact that filtering affects 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the B- channel and Audio Tap trace levels only. Also MAINT driver will 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds select the right trace ID by itself 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_WRITE_SELECTIVE_TRACE_FILTER: 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!mask) { 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = diva_set_trace_filter (1, "*"); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (mask < sizeof(data)) { 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) { 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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: 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) { 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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:{ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_spin_lock_magic_t old_irql; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word size; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_dbg_entry_head_t *pmsg; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byte *pbuf; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(pbuf = diva_os_malloc(0, mask))) { 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENOMEM); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(;;) { 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(pmsg = 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_get_message(&size, &old_irql))) { 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size > mask) { 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_ack_message(0, &old_irql); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = size; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(pbuf, pmsg, size); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_ack_message(1, &old_irql); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((count < size) || 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_copy_to_user (NULL, buf, (void *) pbuf, size)) 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_free(0, pbuf); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case DITRACE_READ_TRACE_ENTRYS:{ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_spin_lock_magic_t old_irql; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word size; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_dbg_entry_head_t *pmsg; 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds byte *pbuf = NULL; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int written = 0; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mask < 4096) { 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EINVAL; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(pbuf = diva_os_malloc(0, mask))) { 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENOMEM); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (;;) { 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(pmsg = 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_get_message(&size, &old_irql))) { 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((size + 8) > mask) { 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_ack_message(0, &old_irql); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write entry length 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = (byte) size; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = (byte) (size >> 8); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Write message 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&pbuf[written], pmsg, size); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_maint_ack_message(1, &old_irql); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds written += size; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask -= (size + 4); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pbuf[written++] = 0; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = -EFAULT; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = written; 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_free(0, pbuf); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 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 && 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (!(*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) { 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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) { 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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())) { 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds diva_os_free (0, buffer); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&MAdapter, 0, sizeof(MAdapter)); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintf = no_printf; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 371