#include #include #include #include #include #include #include #include #include #include "drivers/scsi/scsi.h" #include "drivers/scsi/hosts.h" #include #include #include #include #include #include /* #include #include */ #if defined(MODULE) || defined(PCMCIA) #include #endif #if defined(PCMCIA) # undef MODULE #endif #include "drivers/scsi/nins32.h" #ifndef VERSION # define VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) #endif #include // #if (LINUX_VERSION_CODE > VERSION(1,2,13)) #include /* to get disk capacity */ #endif static Scsi_Host_Template driver_template = (Scsi_Host_Template)NINJA32BI; static dev_node_t *nins32_attach(dev_locator_t *loc); static void nins32_detach(dev_node_t *node); struct driver_operations nins32_ops = { "nins32_cb", nins32_attach, NULL, NULL, nins32_detach }; static dev_node_t *nins32_attach(dev_locator_t *loc) { u_char bus, devfn; Scsi_Device *dev; dev_node_t *node; int n = 0; #if (LINUX_VERSION_CODE >= VERSION(2,1,75)) struct Scsi_Host *host; #endif Ns3DebugPrint(0x20,(__FUNCTION__ " \n")); if (loc->bus != LOC_PCI) return NULL; bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; Ns3DebugPrint(0x20,(__FUNCTION__ " (bus %d, function %d)\n",bus, devfn)); #if (LINUX_VERSION_CODE >= VERSION(2,1,23)) driver_template.module = &__this_module; #else driver_template.usage_count = &GET_USE_COUNT(__this_module); #endif Ns3DebugPrint(0x20,(__FUNCTION__ " sg_tablesize[%x]\n",driver_template.sg_tablesize)); scsi_register_module(MODULE_SCSI_HA, &driver_template); node = kmalloc(7 * sizeof(dev_node_t), GFP_KERNEL); #if (LINUX_VERSION_CODE < VERSION(2,1,75)) for (dev = scsi_devices; dev; dev = dev->next) { if (dev->host->hostt == &driver_template) { #else for (host = scsi_hostlist; host; host = host->next) { if (host->hostt == &driver_template) for (dev = host->host_queue; dev; dev = dev->next) { #endif u_long arg[2], id; kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + ((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000); node[n].minor = 0; switch (dev->type) { case TYPE_TAPE: node[n].major = SCSI_TAPE_MAJOR; sprintf(node[n].dev_name, "st#%04lx", id); break; case TYPE_DISK: case TYPE_MOD: node[n].major = SCSI_DISK0_MAJOR; sprintf(node[n].dev_name, "sd#%04lx", id); break; case TYPE_ROM: case TYPE_WORM: node[n].major = SCSI_CDROM_MAJOR; sprintf(node[n].dev_name, "sr#%04lx", id); break; default: node[n].major = SCSI_GENERIC_MAJOR; sprintf(node[n].dev_name, "sg#%04lx", id); break; } if (n) node[n-1].next = &node[n]; n++; } } if (n == 0) { printk(KERN_INFO "nins32_cs: no SCSI devices found\n"); nins32_detach(node); return NULL; } else { node[n-1].next = NULL; } MOD_INC_USE_COUNT; return node; } static void nins32_detach(dev_node_t *node) { MOD_DEC_USE_COUNT; Ns3DebugPrint(0x20,(__FUNCTION__ " \n")); scsi_unregister_module(MODULE_SCSI_HA, &driver_template); if (node) kfree(node); } /*====================================================================*/ int init_module(void) { Ns3DebugPrint(0x20,(__FUNCTION__ " in\n")); register_driver(&nins32_ops); return 0; } void cleanup_module(void) { Ns3DebugPrint(0x20,(__FUNCTION__ " nins32_cs: unloading\n")); unregister_driver(&nins32_ops); }