1 /*======================================================================
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
6 Ver.2.8 Support 32bit MMIO mode
7 Support Synchronous Data Transfer Request (SDTR) mode
8 Ver.2.0 Support 32bit PIO mode
9 Ver.1.1.2 Fix for scatter list buffer exceeds
10 Ver.1.1 Support scatter list
11 Ver.0.1 Initial version
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
16 ======================================================================*/
18 /***********************************************************************
19 This driver is for these PCcards.
21 I-O DATA PCSC-F (Workbit NinjaSCSI-3)
22 "WBT", "NinjaSCSI-3", "R1.0"
23 I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
24 "IO DATA", "CBSC16 ", "1"
26 ***********************************************************************/
28 /* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */
30 #include <linux/version.h>
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/sched.h>
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/timer.h>
38 #include <linux/ioport.h>
39 #include <linux/delay.h>
40 #include <linux/interrupt.h>
41 #include <linux/module.h>
42 #include <linux/major.h>
43 #include <linux/blkdev.h>
44 #include <linux/stat.h>
49 #include <../drivers/scsi/scsi.h>
50 #include <../drivers/scsi/hosts.h>
52 #include <scsi/scsi.h>
53 #include <scsi/scsi_ioctl.h>
55 #include <pcmcia/version.h>
56 #include <pcmcia/cs_types.h>
57 #include <pcmcia/cs.h>
58 #include <pcmcia/cistpl.h>
59 #include <pcmcia/cisreg.h>
60 #include <pcmcia/ds.h>
64 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
65 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
66 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
68 MODULE_LICENSE("GPL");
73 /*====================================================================*/
74 /* Parameters that can be set with 'insmod' */
76 static unsigned int irq_mask = 0xffff;
77 MODULE_PARM (irq_mask, "i");
78 MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
80 static int irq_list[4] = { -1 };
81 MODULE_PARM (irq_list, "1-4i");
82 MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
84 static int nsp_burst_mode = BURST_MEM32;
85 MODULE_PARM (nsp_burst_mode, "i");
86 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
88 /* Release IO ports after configuration? */
89 static int free_ports = 0;
90 MODULE_PARM (free_ports, "i");
91 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
93 /* /usr/src/linux/drivers/scsi/hosts.h */
94 static Scsi_Host_Template nsp_driver_template = {
95 .proc_name = "nsp_cs",
96 .proc_info = nsp_proc_info,
97 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
98 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
99 .detect = nsp_detect_old,
100 .release = nsp_release_old,
103 .queuecommand = nsp_queuecommand,
104 /* .eh_strategy_handler = nsp_eh_strategy,*/
105 /* .eh_abort_handler = nsp_eh_abort,*/
106 /* .eh_device_reset_handler = nsp_eh_device_reset,*/
107 .eh_bus_reset_handler = nsp_eh_bus_reset,
108 .eh_host_reset_handler = nsp_eh_host_reset,
110 .this_id = NSP_INITIATOR_ID,
111 .sg_tablesize = SG_ALL,
113 .use_clustering = DISABLE_CLUSTERING,
114 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
115 .use_new_eh_code = 1,
119 static dev_link_t *dev_list = NULL;
120 static dev_info_t dev_info = {"nsp_cs"};
122 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
130 # define NSP_DEBUG_MASK 0x000000
131 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
132 # define nsp_dbg(mask, args...) /* */
134 # define NSP_DEBUG_MASK 0xffffff
135 # define nsp_msg(type, args...) \
136 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
137 # define nsp_dbg(mask, args...) \
138 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
141 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
142 #define NSP_DEBUG_REGISTER BIT(1)
143 #define NSP_DEBUG_AUTOSCSI BIT(2)
144 #define NSP_DEBUG_INTR BIT(3)
145 #define NSP_DEBUG_SGLIST BIT(4)
146 #define NSP_DEBUG_BUSFREE BIT(5)
147 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
148 #define NSP_DEBUG_RESELECTION BIT(7)
149 #define NSP_DEBUG_MSGINOCCUR BIT(8)
150 #define NSP_DEBUG_EEPROM BIT(9)
151 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
152 #define NSP_DEBUG_BUSRESET BIT(11)
153 #define NSP_DEBUG_RESTART BIT(12)
154 #define NSP_DEBUG_SYNC BIT(13)
155 #define NSP_DEBUG_WAIT BIT(14)
156 #define NSP_DEBUG_TARGETFLAG BIT(15)
157 #define NSP_DEBUG_PROC BIT(16)
158 #define NSP_DEBUG_INIT BIT(17)
159 #define NSP_DEBUG_DATA_IO BIT(18)
160 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
162 #define NSP_DEBUG_BUF_LEN 150
164 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
167 char buf[NSP_DEBUG_BUF_LEN];
170 vsnprintf(buf, sizeof(buf), fmt, args);
174 printk("%snsp_cs: %s\n", type, buf);
176 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
181 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
184 char buf[NSP_DEBUG_BUF_LEN];
187 vsnprintf(buf, sizeof(buf), fmt, args);
190 if (mask & NSP_DEBUG_MASK) {
191 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
196 /***********************************************************/
198 /*====================================================
199 * Clenaup parameters and call done() functions.
200 * You must be set SCpnt->result before call this function.
202 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
204 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
206 data->CurrentSC = NULL;
208 SCpnt->scsi_done(SCpnt);
211 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
214 /*unsigned int host_id = SCpnt->device->host->this_id;*/
215 /*unsigned int base = SCpnt->device->host->io_port;*/
216 unsigned char target = SCpnt->device->id;
218 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
220 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
221 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
222 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
224 SCpnt->scsi_done = done;
226 if (data->CurrentSC != NULL) {
227 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
228 SCpnt->result = DID_BAD_TARGET << 16;
229 nsp_scsi_done(SCpnt);
230 return SCSI_MLQUEUE_HOST_BUSY;
234 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
235 This makes kernel crash when suspending... */
236 if (data->ScsiInfo->stop != 0) {
237 nsp_msg(KERN_INFO, "suspending device. reject command.");
238 SCpnt->result = DID_BAD_TARGET << 16;
239 nsp_scsi_done(SCpnt);
240 return SCSI_MLQUEUE_HOST_BUSY;
246 data->CurrentSC = SCpnt;
248 SCpnt->SCp.Status = CHECK_CONDITION;
249 SCpnt->SCp.Message = 0;
250 SCpnt->SCp.have_data_in = IO_UNKNOWN;
251 SCpnt->SCp.sent_command = 0;
252 SCpnt->SCp.phase = PH_UNDETERMINED;
253 SCpnt->resid = SCpnt->request_bufflen;
255 /* setup scratch area
256 SCp.ptr : buffer pointer
257 SCp.this_residual : buffer length
258 SCp.buffer : next buffer
259 SCp.buffers_residual : left buffers in list
260 SCp.phase : current state of the command */
262 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
263 SCpnt->SCp.ptr = BUFFER_ADDR;
264 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
265 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
267 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
268 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
269 SCpnt->SCp.buffer = NULL;
270 SCpnt->SCp.buffers_residual = 0;
273 if (nsphw_start_selection(SCpnt) == FALSE) {
274 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
275 SCpnt->result = DID_BUS_BUSY << 16;
276 nsp_scsi_done(SCpnt);
277 return SCSI_MLQUEUE_DEVICE_BUSY;
281 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
289 * setup PIO FIFO transfer mode and enable/disable to data out
291 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
293 unsigned int base = data->BaseAddress;
294 unsigned char transfer_mode_reg;
296 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
298 if (enabled != FALSE) {
299 transfer_mode_reg = TRANSFER_GO | BRAIND;
301 transfer_mode_reg = 0;
304 transfer_mode_reg |= data->TransferMode;
306 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
309 static void nsphw_init_sync(nsp_hw_data *data)
311 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
317 /* setup sync data */
318 for ( i = 0; i < NUMBER(data->Sync); i++ ) {
319 data->Sync[i] = tmp_sync;
324 * Initialize Ninja hardware
326 static int nsphw_init(nsp_hw_data *data)
328 unsigned int base = data->BaseAddress;
330 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
332 data->ScsiClockDiv = CLOCK_40M | FAST_20;
333 data->CurrentSC = NULL;
335 data->TransferMode = MODE_IO8;
337 nsphw_init_sync(data);
339 /* block all interrupts */
340 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
342 /* setup SCSI interface */
343 nsp_write(base, IFSELECT, IF_IFSEL);
345 nsp_index_write(base, SCSIIRQMODE, 0);
347 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
348 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
350 nsp_index_write(base, PARITYCTRL, 0);
351 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
356 /* setup fifo asic */
357 nsp_write(base, IFSELECT, IF_REGSEL);
358 nsp_index_write(base, TERMPWRCTRL, 0);
359 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
360 nsp_msg(KERN_INFO, "terminator power on");
361 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
364 nsp_index_write(base, TIMERCOUNT, 0);
365 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
367 nsp_index_write(base, SYNCREG, 0);
368 nsp_index_write(base, ACKWIDTH, 0);
370 /* enable interrupts and ack them */
371 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
374 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
376 nsp_setup_fifo(data, FALSE);
382 * Start selection phase
384 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
386 unsigned int host_id = SCpnt->device->host->this_id;
387 unsigned int base = SCpnt->device->host->io_port;
388 unsigned char target = SCpnt->device->id;
389 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
391 unsigned char phase, arbit;
393 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
395 phase = nsp_index_read(base, SCSIBUSMON);
396 if(phase != BUSMON_BUS_FREE) {
397 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
401 /* start arbitration */
402 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
403 SCpnt->SCp.phase = PH_ARBSTART;
404 nsp_index_write(base, SETARBIT, ARBIT_GO);
408 /* XXX: what a stupid chip! */
409 arbit = nsp_index_read(base, ARBITSTATUS);
410 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
411 udelay(1); /* hold 1.2us */
412 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
415 if (!(arbit & ARBIT_WIN)) {
416 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
417 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
421 /* assert select line */
422 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
423 SCpnt->SCp.phase = PH_SELSTART;
424 udelay(3); /* wait 2.4us */
425 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
426 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
427 udelay(2); /* wait >1.2us */
428 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
429 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
430 /*udelay(1);*/ /* wait >90ns */
431 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
433 /* check selection timeout */
434 nsp_start_timer(SCpnt, 1000/51);
435 data->SelectionTimeOut = 1;
440 struct nsp_sync_table {
441 unsigned int min_period;
442 unsigned int max_period;
443 unsigned int chip_period;
444 unsigned int ack_width;
447 static struct nsp_sync_table nsp_sync_table_40M[] = {
448 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
449 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
450 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
451 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
455 static struct nsp_sync_table nsp_sync_table_20M[] = {
456 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
457 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
458 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
463 * setup synchronous data transfer mode
465 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
467 unsigned char target = SCpnt->device->id;
468 // unsigned char lun = SCpnt->device->lun;
469 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
470 sync_data *sync = &(data->Sync[target]);
471 struct nsp_sync_table *sync_table;
472 unsigned int period, offset;
476 nsp_dbg(NSP_DEBUG_SYNC, "in");
478 period = sync->SyncPeriod;
479 offset = sync->SyncOffset;
481 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
483 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
484 sync_table = nsp_sync_table_20M;
486 sync_table = nsp_sync_table_40M;
489 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
490 if ( period >= sync_table->min_period &&
491 period <= sync_table->max_period ) {
496 if (period != 0 && sync_table->max_period == 0) {
498 * No proper period/offset found
500 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
502 sync->SyncPeriod = 0;
503 sync->SyncOffset = 0;
504 sync->SyncRegister = 0;
510 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
511 (offset & SYNCREG_OFFSET_MASK);
512 sync->AckWidth = sync_table->ack_width;
514 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
521 * start ninja hardware timer
523 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
525 unsigned int base = SCpnt->device->host->io_port;
526 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
528 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
529 data->TimerCount = time;
530 nsp_index_write(base, TIMERCOUNT, time);
534 * wait for bus phase change
536 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
538 unsigned int base = SCpnt->device->host->io_port;
542 //nsp_dbg(NSP_DEBUG_INTR, "in");
547 reg = nsp_index_read(base, SCSIBUSMON);
551 } while ((time_out-- != 0) && (reg & mask) != 0);
554 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
563 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
564 unsigned char current_phase,
567 unsigned int base = SCpnt->device->host->io_port;
569 unsigned char phase, i_src;
571 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
575 phase = nsp_index_read(base, SCSIBUSMON);
577 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
580 i_src = nsp_read(base, IRQSTATUS);
581 if (i_src & IRQSTATUS_SCSI) {
582 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
585 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
586 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
589 } while(time_out-- != 0);
591 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
596 * transfer SCSI message
598 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
600 unsigned int base = SCpnt->device->host->io_port;
601 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
602 char *buf = data->MsgBuffer;
603 int len = MIN(MSGBUF_SIZE, data->MsgLen);
607 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
608 for (ptr = 0; len > 0; len--, ptr++) {
610 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
612 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
616 /* if last byte, negate ATN */
617 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
618 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
621 /* read & write message */
622 if (phase & BUSMON_IO) {
623 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
624 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
626 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
627 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
629 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
636 * get extra SCSI data from fifo
638 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
640 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
643 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
645 if (SCpnt->SCp.have_data_in != IO_IN) {
649 count = nsp_fifo_count(SCpnt);
650 if (data->FifoCount == count) {
651 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
657 * data phase skip only occures in case of SCSI_LOW_READ
659 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
660 SCpnt->SCp.phase = PH_DATA;
662 nsp_setup_fifo(data, FALSE);
670 static int nsp_reselected(Scsi_Cmnd *SCpnt)
672 unsigned int base = SCpnt->device->host->io_port;
673 unsigned int host_id = SCpnt->device->host->this_id;
674 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
675 unsigned char bus_reg;
676 unsigned char id_reg, tmp;
679 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
681 id_reg = nsp_index_read(base, RESELECTID);
682 tmp = id_reg & (~BIT(host_id));
692 if (SCpnt->device->id != target) {
693 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
696 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
699 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
700 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
701 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
707 * count how many data transferd
709 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
711 unsigned int base = SCpnt->device->host->io_port;
713 unsigned int l, m, h, dummy;
715 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
717 l = nsp_index_read(base, TRANSFERCOUNT);
718 m = nsp_index_read(base, TRANSFERCOUNT);
719 h = nsp_index_read(base, TRANSFERCOUNT);
720 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
722 count = (h << 16) | (m << 8) | (l << 0);
724 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
730 #define RFIFO_CRIT 64
731 #define WFIFO_CRIT 64
734 * read data in DATA IN phase
736 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
738 unsigned int base = SCpnt->device->host->io_port;
739 unsigned long mmio_base = SCpnt->device->host->base;
740 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
743 unsigned char stat, fifo_stat;
745 ocount = data->FifoCount;
747 nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
748 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
752 while ((time_out-- != 0) &&
753 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
755 stat = nsp_index_read(base, SCSIBUSMON);
756 stat &= BUSMON_PHASE_MASK;
759 res = nsp_fifo_count(SCpnt) - ocount;
760 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
761 if (res == 0) { /* if some data avilable ? */
762 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
763 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
766 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
771 fifo_stat = nsp_read(base, FIFOSTATUS);
772 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
773 stat == BUSPHASE_DATA_IN) {
777 res = MIN(res, SCpnt->SCp.this_residual);
779 switch (data->TransferMode) {
781 res &= ~(BIT(1)|BIT(0)); /* align 4 */
782 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
785 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
789 res &= ~(BIT(1)|BIT(0)); /* align 4 */
790 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
794 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
799 SCpnt->SCp.ptr += res;
800 SCpnt->SCp.this_residual -= res;
802 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
804 /* go to next scatter list if available */
805 if (SCpnt->SCp.this_residual == 0 &&
806 SCpnt->SCp.buffers_residual != 0 ) {
807 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
808 SCpnt->SCp.buffers_residual--;
810 SCpnt->SCp.ptr = BUFFER_ADDR;
811 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
814 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
818 data->FifoCount = ocount;
821 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
822 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
824 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
825 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
829 * write data in DATA OUT phase
831 static void nsp_pio_write(Scsi_Cmnd *SCpnt)
833 unsigned int base = SCpnt->device->host->io_port;
834 unsigned long mmio_base = SCpnt->device->host->base;
835 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
840 ocount = data->FifoCount;
842 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
843 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
847 while ((time_out-- != 0) &&
848 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
849 stat = nsp_index_read(base, SCSIBUSMON);
850 stat &= BUSMON_PHASE_MASK;
852 if (stat != BUSPHASE_DATA_OUT) {
853 res = ocount - nsp_fifo_count(SCpnt);
855 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
856 /* Put back pointer */
858 SCpnt->SCp.ptr -= res;
859 SCpnt->SCp.this_residual += res;
865 res = ocount - nsp_fifo_count(SCpnt);
866 if (res > 0) { /* write all data? */
867 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
871 res = MIN(SCpnt->SCp.this_residual, WFIFO_CRIT);
873 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
874 switch (data->TransferMode) {
876 res &= ~(BIT(1)|BIT(0)); /* align 4 */
877 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
880 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
884 res &= ~(BIT(1)|BIT(0)); /* align 4 */
885 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
889 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
894 SCpnt->SCp.ptr += res;
895 SCpnt->SCp.this_residual -= res;
898 /* go to next scatter list if available */
899 if (SCpnt->SCp.this_residual == 0 &&
900 SCpnt->SCp.buffers_residual != 0 ) {
901 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
902 SCpnt->SCp.buffers_residual--;
904 SCpnt->SCp.ptr = BUFFER_ADDR;
905 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
910 data->FifoCount = ocount;
913 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
915 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
916 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
922 * setup synchronous/asynchronous data transfer mode
924 static int nsp_nexus(Scsi_Cmnd *SCpnt)
926 unsigned int base = SCpnt->device->host->io_port;
927 unsigned char target = SCpnt->device->id;
928 // unsigned char lun = SCpnt->device->lun;
929 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
930 sync_data *sync = &(data->Sync[target]);
932 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
934 /* setup synch transfer registers */
935 nsp_index_write(base, SYNCREG, sync->SyncRegister);
936 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
938 if (SCpnt->use_sg == 0 ||
939 SCpnt->resid % 4 != 0 ||
940 SCpnt->resid <= PAGE_SIZE ) {
941 data->TransferMode = MODE_IO8;
942 } else if (nsp_burst_mode == BURST_MEM32) {
943 data->TransferMode = MODE_MEM32;
944 } else if (nsp_burst_mode == BURST_IO32) {
945 data->TransferMode = MODE_IO32;
947 data->TransferMode = MODE_IO8;
950 /* setup pdma fifo */
951 nsp_setup_fifo(data, TRUE);
953 /* clear ack counter */
955 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
963 #include "nsp_message.c"
967 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
970 unsigned char irq_status, irq_phase, phase;
972 unsigned char target, lun;
973 unsigned int *sync_neg;
978 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
979 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
981 if ( dev_id != NULL &&
982 ((scsi_info_t *)dev_id)->host != NULL ) {
983 scsi_info_t *info = (scsi_info_t *)dev_id;
985 data = (nsp_hw_data *)info->host->hostdata;
987 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
991 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
993 base = data->BaseAddress;
994 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
999 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
1000 irq_status = nsp_read(base, IRQSTATUS);
1001 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
1002 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
1003 nsp_write(base, IRQCONTROL, 0);
1004 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
1009 * Do not read an irq_phase register if no scsi phase interrupt.
1010 * Unless, you should lose a scsi phase interrupt.
1012 phase = nsp_index_read(base, SCSIBUSMON);
1013 if((irq_status & IRQSTATUS_SCSI) != 0) {
1014 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1019 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1022 * timer interrupt handler (scsi vs timer interrupts)
1024 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1025 if (data->TimerCount != 0) {
1026 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1027 nsp_index_write(base, TIMERCOUNT, 0);
1028 nsp_index_write(base, TIMERCOUNT, 0);
1029 data->TimerCount = 0;
1032 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1033 data->SelectionTimeOut == 0) {
1034 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1035 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1039 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1041 if ((irq_status & IRQSTATUS_SCSI) &&
1042 (irq_phase & SCSI_RESET_IRQ)) {
1043 nsp_msg(KERN_ERR, "bus reset (power off?)");
1046 nsp_bus_reset(data);
1048 if(data->CurrentSC != NULL) {
1049 tmpSC = data->CurrentSC;
1050 tmpSC->result = (DID_RESET << 16) |
1051 ((tmpSC->SCp.Message & 0xff) << 8) |
1052 ((tmpSC->SCp.Status & 0xff) << 0);
1053 nsp_scsi_done(tmpSC);
1058 if (data->CurrentSC == NULL) {
1059 nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
1061 nsp_bus_reset(data);
1065 tmpSC = data->CurrentSC;
1066 target = tmpSC->device->id;
1067 lun = tmpSC->device->lun;
1068 sync_neg = &(data->Sync[target].SyncNegotiation);
1071 * parse hardware SCSI irq reasons register
1073 if (irq_status & IRQSTATUS_SCSI) {
1074 if (irq_phase & RESELECT_IRQ) {
1075 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1076 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1077 if (nsp_reselected(tmpSC) != FALSE) {
1082 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1087 //show_phase(tmpSC);
1089 switch(tmpSC->SCp.phase) {
1091 // *sync_neg = SYNC_NOT_YET;
1092 if ((phase & BUSMON_BSY) == 0) {
1093 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1094 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1095 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1096 data->SelectionTimeOut = 0;
1097 nsp_index_write(base, SCSIBUSCTRL, 0);
1099 tmpSC->result = DID_TIME_OUT << 16;
1100 nsp_scsi_done(tmpSC);
1104 data->SelectionTimeOut += 1;
1105 nsp_start_timer(tmpSC, 1000/51);
1109 /* attention assert */
1110 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1111 data->SelectionTimeOut = 0;
1112 tmpSC->SCp.phase = PH_SELECTED;
1113 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1115 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1121 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1122 // *sync_neg = SYNC_NOT_YET;
1123 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1125 tmpSC->result = DID_ABORT << 16;
1126 nsp_scsi_done(tmpSC);
1131 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1140 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1142 /* normal disconnect */
1143 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1144 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1145 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1147 //*sync_neg = SYNC_NOT_YET;
1149 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1150 tmpSC->result = (DID_OK << 16) |
1151 ((tmpSC->SCp.Message & 0xff) << 8) |
1152 ((tmpSC->SCp.Status & 0xff) << 0);
1153 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1154 nsp_scsi_done(tmpSC);
1163 /* check unexpected bus free state */
1165 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1167 *sync_neg = SYNC_NG;
1168 tmpSC->result = DID_ERROR << 16;
1169 nsp_scsi_done(tmpSC);
1173 switch (phase & BUSMON_PHASE_MASK) {
1174 case BUSPHASE_COMMAND:
1175 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1176 if ((phase & BUSMON_REQ) == 0) {
1177 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1181 tmpSC->SCp.phase = PH_COMMAND;
1185 /* write scsi command */
1186 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1187 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1188 for (i = 0; i < tmpSC->cmd_len; i++) {
1189 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1191 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1194 case BUSPHASE_DATA_OUT:
1195 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1197 tmpSC->SCp.phase = PH_DATA;
1198 tmpSC->SCp.have_data_in = IO_OUT;
1200 nsp_pio_write(tmpSC);
1204 case BUSPHASE_DATA_IN:
1205 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1207 tmpSC->SCp.phase = PH_DATA;
1208 tmpSC->SCp.have_data_in = IO_IN;
1210 nsp_pio_read(tmpSC);
1214 case BUSPHASE_STATUS:
1215 nsp_dataphase_bypass(tmpSC);
1216 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1218 tmpSC->SCp.phase = PH_STATUS;
1220 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1221 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1225 case BUSPHASE_MESSAGE_OUT:
1226 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1227 if ((phase & BUSMON_REQ) == 0) {
1231 tmpSC->SCp.phase = PH_MSG_OUT;
1233 //*sync_neg = SYNC_NOT_YET;
1235 data->MsgLen = i = 0;
1236 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1238 if (*sync_neg == SYNC_NOT_YET) {
1239 data->Sync[target].SyncPeriod = 0;
1240 data->Sync[target].SyncOffset = 0;
1243 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1244 data->MsgBuffer[i] = 3; i++;
1245 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1246 data->MsgBuffer[i] = 0x0c; i++;
1247 data->MsgBuffer[i] = 15; i++;
1252 nsp_analyze_sdtr(tmpSC);
1254 nsp_message_out(tmpSC);
1257 case BUSPHASE_MESSAGE_IN:
1258 nsp_dataphase_bypass(tmpSC);
1259 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1260 if ((phase & BUSMON_REQ) == 0) {
1264 tmpSC->SCp.phase = PH_MSG_IN;
1265 nsp_message_in(tmpSC);
1268 if (*sync_neg == SYNC_NOT_YET) {
1269 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1271 if (data->MsgLen >= 5 &&
1272 data->MsgBuffer[0] == MSG_EXTENDED &&
1273 data->MsgBuffer[1] == 3 &&
1274 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1275 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1276 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1277 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1278 *sync_neg = SYNC_OK;
1280 data->Sync[target].SyncPeriod = 0;
1281 data->Sync[target].SyncOffset = 0;
1282 *sync_neg = SYNC_NG;
1284 nsp_analyze_sdtr(tmpSC);
1288 /* search last messeage byte */
1290 for (i = 0; i < data->MsgLen; i++) {
1291 tmp = data->MsgBuffer[i];
1292 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1293 i += (1 + data->MsgBuffer[i+1]);
1296 tmpSC->SCp.Message = tmp;
1298 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1303 case BUSPHASE_SELECT:
1305 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1310 //nsp_dbg(NSP_DEBUG_INTR, "out");
1314 nsp_start_timer(tmpSC, 1000/102);
1319 #include "nsp_debug.c"
1320 #endif /* NSP_DEBUG */
1322 /*----------------------------------------------------------------*/
1323 /* look for ninja3 card and init if found */
1324 /*----------------------------------------------------------------*/
1325 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
1327 struct Scsi_Host *host; /* registered host structure */
1328 nsp_hw_data *data_b = &nsp_data_base, *data;
1330 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1331 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1332 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1334 host = scsi_register(sht, sizeof(nsp_hw_data));
1337 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1341 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1342 data = (nsp_hw_data *)host->hostdata;
1343 data->ScsiInfo->host = host;
1348 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1350 host->unique_id = data->BaseAddress;
1351 host->io_port = data->BaseAddress;
1352 host->n_io_port = data->NumAddress;
1353 host->irq = data->IrqNumber;
1354 host->base = data->MmioAddress;
1356 spin_lock_init(&(data->Lock));
1358 snprintf(data->nspinfo,
1359 sizeof(data->nspinfo),
1360 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1361 host->io_port, host->io_port + host->n_io_port - 1,
1364 sht->name = data->nspinfo;
1366 nsp_dbg(NSP_DEBUG_INIT, "end");
1369 return host; /* detect done. */
1372 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1373 static int nsp_detect_old(Scsi_Host_Template *sht)
1375 if (nsp_detect(sht) == NULL) {
1378 //MOD_INC_USE_COUNT;
1384 static int nsp_release_old(struct Scsi_Host *shpnt)
1386 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1388 /* PCMCIA Card Service dose same things below. */
1389 /* So we do nothing. */
1391 // free_irq(shpnt->irq, data->ScsiInfo);
1393 //if (shpnt->io_port) {
1394 // release_region(shpnt->io_port, shpnt->n_io_port);
1397 //MOD_DEC_USE_COUNT;
1403 /*----------------------------------------------------------------*/
1404 /* return info string */
1405 /*----------------------------------------------------------------*/
1406 static const char *nsp_info(struct Scsi_Host *shpnt)
1408 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1410 return data->nspinfo;
1414 #define SPRINTF(args...) \
1416 if(length > (pos - buffer)) { \
1417 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1418 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1423 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1424 struct Scsi_Host *host,
1430 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1439 unsigned long flags;
1441 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1442 struct Scsi_Host *host;
1450 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1451 hostno = host->host_no;
1453 /* search this HBA host */
1454 host = scsi_host_hn_get(hostno);
1459 data = (nsp_hw_data *)host->hostdata;
1462 SPRINTF("NinjaSCSI status\n\n");
1463 SPRINTF("Driver version: $Revision: 1.23 $\n");
1464 SPRINTF("SCSI host No.: %d\n", hostno);
1465 SPRINTF("IRQ: %d\n", host->irq);
1466 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1467 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1468 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1470 SPRINTF("burst transfer mode: ");
1471 switch (nsp_burst_mode) {
1488 spin_lock_irqsave(&(data->Lock), flags);
1489 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1490 spin_unlock_irqrestore(&(data->Lock), flags);
1492 SPRINTF("SDTR status\n");
1493 for(id = 0; id < NUMBER(data->Sync); id++) {
1495 SPRINTF("id %d: ", id);
1497 if (id == host->this_id) {
1498 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1502 switch(data->Sync[id].SyncNegotiation) {
1517 if (data->Sync[id].SyncPeriod != 0) {
1518 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1520 SPRINTF(" transfer %d.%dMB/s, offset %d",
1523 data->Sync[id].SyncOffset
1529 thislength = pos - (buffer + offset);
1531 if(thislength < 0) {
1537 thislength = MIN(thislength, length);
1538 *start = buffer + offset;
1544 /*---------------------------------------------------------------*/
1546 /*---------------------------------------------------------------*/
1548 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
1554 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1556 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1558 return nsp_eh_bus_reset(SCpnt);
1562 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
1564 nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
1569 static int nsp_bus_reset(nsp_hw_data *data)
1571 unsigned int base = data->BaseAddress;
1574 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1576 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1577 mdelay(100); /* 100ms */
1578 nsp_index_write(base, SCSIBUSCTRL, 0);
1579 for(i = 0; i < 5; i++) {
1580 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1583 nsphw_init_sync(data);
1585 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1590 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1592 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1594 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1596 return nsp_bus_reset(data);
1599 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1601 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1603 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1611 /**********************************************************************
1613 **********************************************************************/
1615 /*======================================================================
1616 nsp_cs_attach() creates an "instance" of the driver, allocating
1617 local data structures for one device. The device is registered
1620 The dev_link structure is initialized, but we don't actually
1621 configure the card at this point -- we wait until we receive a
1622 card insertion event.
1623 ======================================================================*/
1624 static dev_link_t *nsp_cs_attach(void)
1627 client_reg_t client_reg;
1630 nsp_hw_data *data = &nsp_data_base;
1632 nsp_dbg(NSP_DEBUG_INIT, "in");
1634 /* Create new SCSI device */
1635 info = kmalloc(sizeof(*info), GFP_KERNEL);
1636 if (info == NULL) { return NULL; }
1637 memset(info, 0, sizeof(*info));
1640 data->ScsiInfo = info;
1642 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1644 /* The io structure describes IO port mapping */
1645 link->io.NumPorts1 = 0x10;
1646 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1647 link->io.IOAddrLines = 10; /* not used */
1649 /* Interrupt setup */
1650 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1651 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
1652 if (irq_list[0] == -1) {
1653 link->irq.IRQInfo2 = irq_mask;
1655 for (i = 0; i < 4; i++) {
1656 link->irq.IRQInfo2 |= BIT(irq_list[i]);
1660 /* Interrupt handler */
1661 link->irq.Handler = &nspintr;
1662 link->irq.Instance = info;
1663 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1665 /* General socket configuration */
1666 link->conf.Attributes = CONF_ENABLE_IRQ;
1667 link->conf.Vcc = 50;
1668 link->conf.IntType = INT_MEMORY_AND_IO;
1669 link->conf.Present = PRESENT_OPTION;
1672 /* Register with Card Services */
1673 link->next = dev_list;
1675 client_reg.dev_info = &dev_info;
1676 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
1677 client_reg.EventMask =
1678 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1679 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1680 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1681 client_reg.event_handler = &nsp_cs_event;
1682 client_reg.Version = 0x0210;
1683 client_reg.event_callback_args.client_data = link;
1684 ret = pcmcia_register_client(&link->handle, &client_reg);
1685 if (ret != CS_SUCCESS) {
1686 cs_error(link->handle, RegisterClient, ret);
1687 nsp_cs_detach(link);
1692 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1694 } /* nsp_cs_attach */
1697 /*======================================================================
1698 This deletes a driver "instance". The device is de-registered
1699 with Card Services. If it has been released, all local data
1700 structures are freed. Otherwise, the structures will be freed
1701 when the device is released.
1702 ======================================================================*/
1703 static void nsp_cs_detach(dev_link_t *link)
1707 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1709 /* Locate device structure */
1710 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1711 if (*linkp == link) {
1715 if (*linkp == NULL) {
1719 if (link->state & DEV_CONFIG)
1720 nsp_cs_release(link);
1722 /* Break the link with Card Services */
1724 pcmcia_deregister_client(link->handle);
1727 /* Unlink device structure, free bits */
1728 *linkp = link->next;
1732 } /* nsp_cs_detach */
1735 /*======================================================================
1736 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1737 is received, to configure the PCMCIA socket, and to make the
1738 ethernet device available to the system.
1739 ======================================================================*/
1740 #define CS_CHECK(fn, ret) \
1741 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1742 /*====================================================================*/
1743 static void nsp_cs_config(dev_link_t *link)
1745 client_handle_t handle = link->handle;
1746 scsi_info_t *info = link->priv;
1749 int last_ret, last_fn;
1750 unsigned char tuple_data[64];
1754 cistpl_cftable_entry_t dflt = { 0 };
1755 struct Scsi_Host *host;
1756 nsp_hw_data *data = &nsp_data_base;
1757 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1759 dev_node_t **tail, *node;
1762 nsp_dbg(NSP_DEBUG_INIT, "in");
1764 tuple.DesiredTuple = CISTPL_CONFIG;
1765 tuple.Attributes = 0;
1766 tuple.TupleData = tuple_data;
1767 tuple.TupleDataMax = sizeof(tuple_data);
1768 tuple.TupleOffset = 0;
1769 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1770 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1771 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1772 link->conf.ConfigBase = parse.config.base;
1773 link->conf.Present = parse.config.rmask[0];
1775 /* Configure card */
1776 link->state |= DEV_CONFIG;
1778 /* Look up the current Vcc */
1779 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1780 link->conf.Vcc = conf.Vcc;
1782 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1783 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1785 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1787 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1788 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1791 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1792 if (cfg->index == 0) { goto next_entry; }
1793 link->conf.ConfigIndex = cfg->index;
1795 /* Does this card need audio output? */
1796 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1797 link->conf.Attributes |= CONF_ENABLE_SPKR;
1798 link->conf.Status = CCSR_AUDIO_ENA;
1801 /* Use power settings for Vcc and Vpp if present */
1802 /* Note that the CIS values need to be rescaled */
1803 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1804 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1807 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1808 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1813 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1814 link->conf.Vpp1 = link->conf.Vpp2 =
1815 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1816 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1817 link->conf.Vpp1 = link->conf.Vpp2 =
1818 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1821 /* Do we need to allocate an interrupt? */
1822 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1823 link->conf.Attributes |= CONF_ENABLE_IRQ;
1826 /* IO window settings */
1827 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1828 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1829 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1830 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1831 if (!(io->flags & CISTPL_IO_8BIT))
1832 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1833 if (!(io->flags & CISTPL_IO_16BIT))
1834 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1835 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1836 link->io.BasePort1 = io->win[0].base;
1837 link->io.NumPorts1 = io->win[0].len;
1839 link->io.Attributes2 = link->io.Attributes1;
1840 link->io.BasePort2 = io->win[1].base;
1841 link->io.NumPorts2 = io->win[1].len;
1843 /* This reserves IO space but doesn't actually enable it */
1844 if (pcmcia_request_io(link->handle, &link->io) != 0)
1848 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1850 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1851 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1852 req.Attributes |= WIN_ENABLE;
1853 req.Base = mem->win[0].host_addr;
1854 req.Size = mem->win[0].len;
1855 if (req.Size < 0x1000) {
1858 req.AccessSpeed = 0;
1859 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1861 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1862 if (pcmcia_map_mem_page(link->win, &map) != 0)
1865 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1866 data->MmioLength = req.Size;
1868 /* If we got this far, we're cool! */
1872 nsp_dbg(NSP_DEBUG_INIT, "next");
1874 if (link->io.NumPorts1) {
1875 pcmcia_release_io(link->handle, &link->io);
1877 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1880 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1881 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1883 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1886 if (link->io.BasePort1) {
1887 release_region(link->io.BasePort1, link->io.NumPorts1);
1889 if (link->io.BasePort2) {
1890 release_region(link->io.BasePort2, link->io.NumPorts2);
1894 /* Set port and IRQ */
1895 data->BaseAddress = link->io.BasePort1;
1896 data->NumAddress = link->io.NumPorts1;
1897 data->IrqNumber = link->irq.AssignedIRQ;
1899 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1900 data->BaseAddress, data->NumAddress, data->IrqNumber);
1902 if(nsphw_init(data) == FALSE) {
1906 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1907 host = nsp_detect(&nsp_driver_template);
1909 scsi_register_host(&nsp_driver_template);
1910 for (host = scsi_host_get_next(NULL); host != NULL;
1911 host = scsi_host_get_next(host)) {
1912 if (host->hostt == &nsp_driver_template) {
1919 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1924 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1925 scsi_add_host (host, NULL);
1926 scsi_scan_host(host);
1928 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1929 link->dev = &info->node;
1933 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1937 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1939 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1940 unsigned long arg[2], id;
1941 kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
1942 id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) +
1943 ((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
1944 node = &info->node[info->ndev];
1946 switch (dev->type) {
1948 node->major = SCSI_TAPE_MAJOR;
1949 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1953 node->major = SCSI_DISK0_MAJOR;
1954 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1958 node->major = SCSI_CDROM_MAJOR;
1959 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1962 node->major = SCSI_GENERIC_MAJOR;
1963 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1966 *tail = node; tail = &node->next;
1968 info->host = dev->host;
1972 if (info->ndev == 0) {
1973 nsp_msg(KERN_INFO, "no SCSI devices found");
1975 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1978 /* Finally, report what we've done */
1979 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1980 link->conf.ConfigIndex,
1981 link->conf.Vcc/10, link->conf.Vcc%10);
1982 if (link->conf.Vpp1) {
1983 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1985 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1986 printk(", irq %d", link->irq.AssignedIRQ);
1988 if (link->io.NumPorts1) {
1989 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1990 link->io.BasePort1+link->io.NumPorts1-1);
1992 if (link->io.NumPorts2)
1993 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1994 link->io.BasePort2+link->io.NumPorts2-1);
1996 printk(", mem 0x%06lx-0x%06lx", req.Base,
1997 req.Base+req.Size-1);
2000 link->state &= ~DEV_CONFIG_PENDING;
2004 nsp_dbg(NSP_DEBUG_INIT, "config fail");
2005 cs_error(link->handle, last_fn, last_ret);
2006 nsp_cs_release(link);
2009 } /* nsp_cs_config */
2013 /*======================================================================
2014 After a card is removed, nsp_cs_release() will unregister the net
2015 device, and release the PCMCIA configuration. If the device is
2016 still open, this will be postponed until it is closed.
2017 ======================================================================*/
2018 static void nsp_cs_release(dev_link_t *link)
2020 scsi_info_t *info = link->priv;
2021 nsp_hw_data *data = NULL;
2023 if (info->host == NULL) {
2024 nsp_msg(KERN_DEBUG, "unexpected card release call.");
2026 data = (nsp_hw_data *)info->host->hostdata;
2029 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
2031 /* Unlink the device chain */
2032 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2033 if (info->host != NULL) {
2034 scsi_remove_host(info->host);
2037 scsi_unregister_host(&nsp_driver_template);
2043 iounmap((void *)(data->MmioAddress));
2045 pcmcia_release_window(link->win);
2047 pcmcia_release_configuration(link->handle);
2048 if (link->io.NumPorts1) {
2049 pcmcia_release_io(link->handle, &link->io);
2051 if (link->irq.AssignedIRQ) {
2052 pcmcia_release_irq(link->handle, &link->irq);
2054 link->state &= ~DEV_CONFIG;
2055 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2056 if (info->host != NULL) {
2057 scsi_host_put(info->host);
2060 } /* nsp_cs_release */
2062 /*======================================================================
2064 The card status event handler. Mostly, this schedules other
2065 stuff to run after an event is received. A CARD_REMOVAL event
2066 also sets some flags to discourage the net drivers from trying
2067 to talk to the card any more.
2069 When a CARD_REMOVAL event is received, we immediately set a flag
2070 to block future accesses to this device. All the functions that
2071 actually access the device should check this flag to make sure
2072 the card is still present.
2074 ======================================================================*/
2075 static int nsp_cs_event(event_t event,
2077 event_callback_args_t *args)
2079 dev_link_t *link = args->client_data;
2080 scsi_info_t *info = link->priv;
2083 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2086 case CS_EVENT_CARD_REMOVAL:
2087 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2088 link->state &= ~DEV_PRESENT;
2089 if (link->state & DEV_CONFIG) {
2090 ((scsi_info_t *)link->priv)->stop = 1;
2091 nsp_cs_release(link);
2095 case CS_EVENT_CARD_INSERTION:
2096 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2097 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2098 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2099 info->bus = args->bus;
2101 nsp_cs_config(link);
2104 case CS_EVENT_PM_SUSPEND:
2105 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2106 link->state |= DEV_SUSPEND;
2107 /* Fall through... */
2108 case CS_EVENT_RESET_PHYSICAL:
2109 /* Mark the device as stopped, to block IO until later */
2110 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2112 if (info->host != NULL) {
2113 nsp_msg(KERN_INFO, "clear SDTR status");
2115 data = (nsp_hw_data *)info->host->hostdata;
2117 nsphw_init_sync(data);
2121 if (link->state & DEV_CONFIG) {
2122 pcmcia_release_configuration(link->handle);
2126 case CS_EVENT_PM_RESUME:
2127 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2128 link->state &= ~DEV_SUSPEND;
2129 /* Fall through... */
2130 case CS_EVENT_CARD_RESET:
2131 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2132 if (link->state & DEV_CONFIG) {
2133 pcmcia_request_configuration(link->handle, &link->conf);
2137 if (info->host != NULL) {
2138 nsp_msg(KERN_INFO, "reset host and bus");
2140 data = (nsp_hw_data *)info->host->hostdata;
2143 nsp_bus_reset(data);
2149 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2152 nsp_dbg(NSP_DEBUG_INIT, "end");
2154 } /* nsp_cs_event */
2156 /*======================================================================*
2157 * module entry point
2158 *====================================================================*/
2159 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2160 static struct pcmcia_driver nsp_driver = {
2161 .owner = THIS_MODULE,
2165 .attach = nsp_cs_attach,
2166 .detach = nsp_cs_detach,
2170 static int __init nsp_cs_init(void)
2172 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2173 nsp_msg(KERN_INFO, "loading...");
2175 return pcmcia_register_driver(&nsp_driver);
2179 nsp_msg(KERN_INFO, "loading...");
2180 pcmcia_get_card_services_info(&serv);
2181 if (serv.Revision != CS_RELEASE_CODE) {
2182 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2185 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2187 nsp_dbg(NSP_DEBUG_INIT, "out");
2192 static void __exit nsp_cs_exit(void)
2194 nsp_msg(KERN_INFO, "unloading...");
2196 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2197 pcmcia_unregister_driver(&nsp_driver);
2199 unregister_pcmcia_driver(&dev_info);
2202 /* XXX: this really needs to move into generic code.. */
2203 while (dev_list != NULL) {
2204 if (dev_list->state & DEV_CONFIG) {
2205 nsp_cs_release(dev_list);
2207 nsp_cs_detach(dev_list);
2212 module_init(nsp_cs_init)
2213 module_exit(nsp_cs_exit)