#include <asm/irq.h>
#include <../drivers/scsi/scsi.h>
-#include <../drivers/scsi/hosts.h>
+#include <scsi/scsi_host.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
-#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
/*====================================================================*/
/* Parameters that can be set with 'insmod' */
-static unsigned int irq_mask = 0xffff;
-MODULE_PARM (irq_mask, "i");
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
-
-static int irq_list[4] = { -1 };
-MODULE_PARM (irq_list, "1-4i");
-MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
-
static int nsp_burst_mode = BURST_MEM32;
-MODULE_PARM (nsp_burst_mode, "i");
+module_param(nsp_burst_mode, int, 0);
MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
/* Release IO ports after configuration? */
static int free_ports = 0;
-MODULE_PARM (free_ports, "i");
+module_param(free_ports, bool, 0);
MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
/* /usr/src/linux/drivers/scsi/hosts.h */
-static Scsi_Host_Template nsp_driver_template = {
+static struct scsi_host_template nsp_driver_template = {
.proc_name = "nsp_cs",
.proc_info = nsp_proc_info,
.name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
#endif
.info = nsp_info,
.queuecommand = nsp_queuecommand,
-/* .eh_strategy_handler = nsp_eh_strategy,*/
/* .eh_abort_handler = nsp_eh_abort,*/
-/* .eh_device_reset_handler = nsp_eh_device_reset,*/
.eh_bus_reset_handler = nsp_eh_bus_reset,
.eh_host_reset_handler = nsp_eh_host_reset,
.can_queue = 1,
#endif
};
-static dev_link_t *dev_list = NULL;
-static dev_info_t dev_info = {"nsp_cs"};
-
static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
#ifdef NSP_DEBUG
/*unsigned int host_id = SCpnt->device->host->this_id;*/
/*unsigned int base = SCpnt->device->host->io_port;*/
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
#endif
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
SCpnt->result = DID_BAD_TARGET << 16;
nsp_scsi_done(SCpnt);
- return SCSI_MLQUEUE_HOST_BUSY;
+ return 0;
}
#if 0
nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
SCpnt->result = DID_BUS_BUSY << 16;
nsp_scsi_done(SCpnt);
- return SCSI_MLQUEUE_DEVICE_BUSY;
+ return 0;
}
{
unsigned int host_id = SCpnt->device->host->this_id;
unsigned int base = SCpnt->device->host->io_port;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
int time_out;
unsigned char phase, arbit;
*/
static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
{
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
// unsigned char lun = SCpnt->device->lun;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
sync_data *sync = &(data->Sync[target]);
target++;
}
- if (SCpnt->device->id != target) {
+ if (scmd_id(SCpnt) != target) {
nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
}
static int nsp_nexus(Scsi_Cmnd *SCpnt)
{
unsigned int base = SCpnt->device->host->io_port;
- unsigned char target = SCpnt->device->id;
+ unsigned char target = scmd_id(SCpnt);
// unsigned char lun = SCpnt->device->lun;
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
sync_data *sync = &(data->Sync[target]);
/*----------------------------------------------------------------*/
/* look for ninja3 card and init if found */
/*----------------------------------------------------------------*/
-static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
+static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
{
struct Scsi_Host *host; /* registered host structure */
nsp_hw_data *data_b = &nsp_data_base, *data;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int nsp_detect_old(Scsi_Host_Template *sht)
+static int nsp_detect_old(struct scsi_host_template *sht)
{
if (nsp_detect(sht) == NULL) {
return 0;
thislength = pos - (buffer + offset);
if(thislength < 0) {
- *start = 0;
+ *start = NULL;
return 0;
}
/* error handler */
/*---------------------------------------------------------------*/
-/*static int nsp_eh_strategy(struct Scsi_Host *Shost)
-{
- return FAILED;
-}*/
-
/*
static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
{
return nsp_eh_bus_reset(SCpnt);
}*/
-/*
-static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
-{
- nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
-
- return FAILED;
-}*/
-
static int nsp_bus_reset(nsp_hw_data *data)
{
unsigned int base = data->BaseAddress;
configure the card at this point -- we wait until we receive a
card insertion event.
======================================================================*/
-static dev_link_t *nsp_cs_attach(void)
+static int nsp_cs_attach(struct pcmcia_device *p_dev)
{
scsi_info_t *info;
- client_reg_t client_reg;
dev_link_t *link;
- int ret, i;
nsp_hw_data *data = &nsp_data_base;
nsp_dbg(NSP_DEBUG_INIT, "in");
/* Create new SCSI device */
info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (info == NULL) { return NULL; }
+ if (info == NULL) { return -ENOMEM; }
memset(info, 0, sizeof(*info));
link = &info->link;
link->priv = info;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
- if (irq_list[0] == -1) {
- link->irq.IRQInfo2 = irq_mask;
- } else {
- for (i = 0; i < 4; i++) {
- link->irq.IRQInfo2 |= BIT(irq_list[i]);
- }
- }
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
/* Interrupt handler */
link->irq.Handler = &nspintr;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
+ link->handle = p_dev;
+ p_dev->instance = link;
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
- client_reg.event_handler = &nsp_cs_event;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = pcmcia_register_client(&link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- nsp_cs_detach(link);
- return NULL;
- }
-
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ nsp_cs_config(link);
nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
- return link;
+ return 0;
} /* nsp_cs_attach */
structures are freed. Otherwise, the structures will be freed
when the device is released.
======================================================================*/
-static void nsp_cs_detach(dev_link_t *link)
+static void nsp_cs_detach(struct pcmcia_device *p_dev)
{
- dev_link_t **linkp;
+ dev_link_t *link = dev_to_instance(p_dev);
nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
- if (*linkp == link) {
- break;
- }
- }
- if (*linkp == NULL) {
- return;
- }
-
- if (link->state & DEV_CONFIG)
+ if (link->state & DEV_CONFIG) {
+ ((scsi_info_t *)link->priv)->stop = 1;
nsp_cs_release(link);
-
- /* Break the link with Card Services */
- if (link->handle) {
- pcmcia_deregister_client(link->handle);
}
- /* Unlink device structure, free bits */
- *linkp = link->next;
kfree(link->priv);
link->priv = NULL;
-
} /* nsp_cs_detach */
struct Scsi_Host *host;
nsp_hw_data *data = &nsp_data_base;
#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
- Scsi_Device *dev;
+ struct scsi_device *dev;
dev_node_t **tail, *node;
#endif
nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
for (dev = host->host_queue; dev != NULL; dev = dev->next) {
- unsigned 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);
+ unsigned long id;
+ id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
+ ((dev->channel & 0x0f) << 8) +
+ ((dev->host->host_no & 0x0f) << 12);
node = &info->node[info->ndev];
node->minor = 0;
switch (dev->type) {
#endif
} /* nsp_cs_release */
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
- When a CARD_REMOVAL event is received, we immediately set a flag
- to block future accesses to this device. All the functions that
- actually access the device should check this flag to make sure
- the card is still present.
-
-======================================================================*/
-static int nsp_cs_event(event_t event,
- int priority,
- event_callback_args_t *args)
+static int nsp_cs_suspend(struct pcmcia_device *dev)
{
- dev_link_t *link = args->client_data;
+ dev_link_t *link = dev_to_instance(dev);
scsi_info_t *info = link->priv;
nsp_hw_data *data;
- nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
+ link->state |= DEV_SUSPEND;
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- nsp_dbg(NSP_DEBUG_INIT, "event: remove");
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- ((scsi_info_t *)link->priv)->stop = 1;
- nsp_cs_release(link);
- }
- break;
+ nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
- case CS_EVENT_CARD_INSERTION:
- nsp_dbg(NSP_DEBUG_INIT, "event: insert");
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
- info->bus = args->bus;
-#endif
- nsp_cs_config(link);
- break;
+ if (info->host != NULL) {
+ nsp_msg(KERN_INFO, "clear SDTR status");
- case CS_EVENT_PM_SUSPEND:
- nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- /* Mark the device as stopped, to block IO until later */
- nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
+ data = (nsp_hw_data *)info->host->hostdata;
- if (info->host != NULL) {
- nsp_msg(KERN_INFO, "clear SDTR status");
+ nsphw_init_sync(data);
+ }
- data = (nsp_hw_data *)info->host->hostdata;
+ info->stop = 1;
- nsphw_init_sync(data);
- }
+ if (link->state & DEV_CONFIG)
+ pcmcia_release_configuration(link->handle);
- info->stop = 1;
- if (link->state & DEV_CONFIG) {
- pcmcia_release_configuration(link->handle);
- }
- break;
+ return 0;
+}
- case CS_EVENT_PM_RESUME:
- nsp_dbg(NSP_DEBUG_INIT, "event: resume");
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- nsp_dbg(NSP_DEBUG_INIT, "event: reset");
- if (link->state & DEV_CONFIG) {
- pcmcia_request_configuration(link->handle, &link->conf);
- }
- info->stop = 0;
+static int nsp_cs_resume(struct pcmcia_device *dev)
+{
+ dev_link_t *link = dev_to_instance(dev);
+ scsi_info_t *info = link->priv;
+ nsp_hw_data *data;
- if (info->host != NULL) {
- nsp_msg(KERN_INFO, "reset host and bus");
+ nsp_dbg(NSP_DEBUG_INIT, "event: resume");
- data = (nsp_hw_data *)info->host->hostdata;
+ link->state &= ~DEV_SUSPEND;
- nsphw_init (data);
- nsp_bus_reset(data);
- }
+ if (link->state & DEV_CONFIG)
+ pcmcia_request_configuration(link->handle, &link->conf);
- break;
+ info->stop = 0;
- default:
- nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
- break;
+ if (info->host != NULL) {
+ nsp_msg(KERN_INFO, "reset host and bus");
+
+ data = (nsp_hw_data *)info->host->hostdata;
+
+ nsphw_init (data);
+ nsp_bus_reset(data);
}
- nsp_dbg(NSP_DEBUG_INIT, "end");
+
return 0;
-} /* nsp_cs_event */
+}
/*======================================================================*
* module entry point
*====================================================================*/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
+static struct pcmcia_device_id nsp_cs_ids[] = {
+ PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
+ PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
+ PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
+ PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
+ PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
+ PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
+ PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
+ PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
+
static struct pcmcia_driver nsp_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "nsp_cs",
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "nsp_cs",
},
- .attach = nsp_cs_attach,
- .detach = nsp_cs_detach,
+ .probe = nsp_cs_attach,
+ .remove = nsp_cs_detach,
+ .id_table = nsp_cs_ids,
+ .suspend = nsp_cs_suspend,
+ .resume = nsp_cs_resume,
};
#endif
pcmcia_unregister_driver(&nsp_driver);
#else
unregister_pcmcia_driver(&dev_info);
-#endif
-
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG) {
}
nsp_cs_detach(dev_list);
}
+#endif
}