From: jbarnes@sgi.com
[wrt350n-kernel.git] / drivers / scsi / pcmcia / nsp_cs.c
blob496c412c88546a854c9d13223c5d7123dc57a38b
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/major.h>
42 #include <linux/blkdev.h>
43 #include <linux/stat.h>
45 #include <asm/io.h>
46 #include <asm/irq.h>
48 #include <../drivers/scsi/scsi.h>
49 #include <scsi/scsi_host.h>
51 #include <scsi/scsi.h>
52 #include <scsi/scsi_ioctl.h>
54 #include <pcmcia/version.h>
55 #include <pcmcia/cs_types.h>
56 #include <pcmcia/cs.h>
57 #include <pcmcia/cistpl.h>
58 #include <pcmcia/cisreg.h>
59 #include <pcmcia/ds.h>
61 #include "nsp_cs.h"
63 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
64 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
65 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
66 #ifdef MODULE_LICENSE
67 MODULE_LICENSE("GPL");
68 #endif
70 #include "nsp_io.h"
72 /*====================================================================*/
73 /* Parameters that can be set with 'insmod' */
75 static int nsp_burst_mode = BURST_MEM32;
76 module_param(nsp_burst_mode, int, 0);
77 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
79 /* Release IO ports after configuration? */
80 static int free_ports = 0;
81 module_param(free_ports, bool, 0);
82 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
84 /* /usr/src/linux/drivers/scsi/hosts.h */
85 static Scsi_Host_Template nsp_driver_template = {
86 .proc_name = "nsp_cs",
87 .proc_info = nsp_proc_info,
88 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
89 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
90 .detect = nsp_detect_old,
91 .release = nsp_release_old,
92 #endif
93 .info = nsp_info,
94 .queuecommand = nsp_queuecommand,
95 /* .eh_strategy_handler = nsp_eh_strategy,*/
96 /* .eh_abort_handler = nsp_eh_abort,*/
97 /* .eh_device_reset_handler = nsp_eh_device_reset,*/
98 .eh_bus_reset_handler = nsp_eh_bus_reset,
99 .eh_host_reset_handler = nsp_eh_host_reset,
100 .can_queue = 1,
101 .this_id = NSP_INITIATOR_ID,
102 .sg_tablesize = SG_ALL,
103 .cmd_per_lun = 1,
104 .use_clustering = DISABLE_CLUSTERING,
105 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
106 .use_new_eh_code = 1,
107 #endif
110 static dev_link_t *dev_list = NULL;
111 static dev_info_t dev_info = {"nsp_cs"};
113 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
118 * debug, error print
120 #ifndef NSP_DEBUG
121 # define NSP_DEBUG_MASK 0x000000
122 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
123 # define nsp_dbg(mask, args...) /* */
124 #else
125 # define NSP_DEBUG_MASK 0xffffff
126 # define nsp_msg(type, args...) \
127 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
128 # define nsp_dbg(mask, args...) \
129 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
130 #endif
132 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
133 #define NSP_DEBUG_REGISTER BIT(1)
134 #define NSP_DEBUG_AUTOSCSI BIT(2)
135 #define NSP_DEBUG_INTR BIT(3)
136 #define NSP_DEBUG_SGLIST BIT(4)
137 #define NSP_DEBUG_BUSFREE BIT(5)
138 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
139 #define NSP_DEBUG_RESELECTION BIT(7)
140 #define NSP_DEBUG_MSGINOCCUR BIT(8)
141 #define NSP_DEBUG_EEPROM BIT(9)
142 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
143 #define NSP_DEBUG_BUSRESET BIT(11)
144 #define NSP_DEBUG_RESTART BIT(12)
145 #define NSP_DEBUG_SYNC BIT(13)
146 #define NSP_DEBUG_WAIT BIT(14)
147 #define NSP_DEBUG_TARGETFLAG BIT(15)
148 #define NSP_DEBUG_PROC BIT(16)
149 #define NSP_DEBUG_INIT BIT(17)
150 #define NSP_DEBUG_DATA_IO BIT(18)
151 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
153 #define NSP_DEBUG_BUF_LEN 150
155 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
157 va_list args;
158 char buf[NSP_DEBUG_BUF_LEN];
160 va_start(args, fmt);
161 vsnprintf(buf, sizeof(buf), fmt, args);
162 va_end(args);
164 #ifndef NSP_DEBUG
165 printk("%snsp_cs: %s\n", type, buf);
166 #else
167 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
168 #endif
171 #ifdef NSP_DEBUG
172 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
174 va_list args;
175 char buf[NSP_DEBUG_BUF_LEN];
177 va_start(args, fmt);
178 vsnprintf(buf, sizeof(buf), fmt, args);
179 va_end(args);
181 if (mask & NSP_DEBUG_MASK) {
182 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
185 #endif
187 /***********************************************************/
189 /*====================================================
190 * Clenaup parameters and call done() functions.
191 * You must be set SCpnt->result before call this function.
193 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
195 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
197 data->CurrentSC = NULL;
199 SCpnt->scsi_done(SCpnt);
202 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
204 #ifdef NSP_DEBUG
205 /*unsigned int host_id = SCpnt->device->host->this_id;*/
206 /*unsigned int base = SCpnt->device->host->io_port;*/
207 unsigned char target = SCpnt->device->id;
208 #endif
209 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
211 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
212 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
213 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
215 SCpnt->scsi_done = done;
217 if (data->CurrentSC != NULL) {
218 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
219 SCpnt->result = DID_BAD_TARGET << 16;
220 nsp_scsi_done(SCpnt);
221 return 0;
224 #if 0
225 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
226 This makes kernel crash when suspending... */
227 if (data->ScsiInfo->stop != 0) {
228 nsp_msg(KERN_INFO, "suspending device. reject command.");
229 SCpnt->result = DID_BAD_TARGET << 16;
230 nsp_scsi_done(SCpnt);
231 return SCSI_MLQUEUE_HOST_BUSY;
233 #endif
235 show_command(SCpnt);
237 data->CurrentSC = SCpnt;
239 SCpnt->SCp.Status = CHECK_CONDITION;
240 SCpnt->SCp.Message = 0;
241 SCpnt->SCp.have_data_in = IO_UNKNOWN;
242 SCpnt->SCp.sent_command = 0;
243 SCpnt->SCp.phase = PH_UNDETERMINED;
244 SCpnt->resid = SCpnt->request_bufflen;
246 /* setup scratch area
247 SCp.ptr : buffer pointer
248 SCp.this_residual : buffer length
249 SCp.buffer : next buffer
250 SCp.buffers_residual : left buffers in list
251 SCp.phase : current state of the command */
252 if (SCpnt->use_sg) {
253 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
254 SCpnt->SCp.ptr = BUFFER_ADDR;
255 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
256 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
257 } else {
258 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
259 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
260 SCpnt->SCp.buffer = NULL;
261 SCpnt->SCp.buffers_residual = 0;
264 if (nsphw_start_selection(SCpnt) == FALSE) {
265 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
266 SCpnt->result = DID_BUS_BUSY << 16;
267 nsp_scsi_done(SCpnt);
268 return 0;
272 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
273 #ifdef NSP_DEBUG
274 data->CmdId++;
275 #endif
276 return 0;
280 * setup PIO FIFO transfer mode and enable/disable to data out
282 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
284 unsigned int base = data->BaseAddress;
285 unsigned char transfer_mode_reg;
287 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
289 if (enabled != FALSE) {
290 transfer_mode_reg = TRANSFER_GO | BRAIND;
291 } else {
292 transfer_mode_reg = 0;
295 transfer_mode_reg |= data->TransferMode;
297 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
300 static void nsphw_init_sync(nsp_hw_data *data)
302 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
303 .SyncPeriod = 0,
304 .SyncOffset = 0
306 int i;
308 /* setup sync data */
309 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
310 data->Sync[i] = tmp_sync;
315 * Initialize Ninja hardware
317 static int nsphw_init(nsp_hw_data *data)
319 unsigned int base = data->BaseAddress;
321 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
323 data->ScsiClockDiv = CLOCK_40M | FAST_20;
324 data->CurrentSC = NULL;
325 data->FifoCount = 0;
326 data->TransferMode = MODE_IO8;
328 nsphw_init_sync(data);
330 /* block all interrupts */
331 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
333 /* setup SCSI interface */
334 nsp_write(base, IFSELECT, IF_IFSEL);
336 nsp_index_write(base, SCSIIRQMODE, 0);
338 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
339 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
341 nsp_index_write(base, PARITYCTRL, 0);
342 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
343 ACK_COUNTER_CLEAR |
344 REQ_COUNTER_CLEAR |
345 HOST_COUNTER_CLEAR);
347 /* setup fifo asic */
348 nsp_write(base, IFSELECT, IF_REGSEL);
349 nsp_index_write(base, TERMPWRCTRL, 0);
350 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
351 nsp_msg(KERN_INFO, "terminator power on");
352 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
355 nsp_index_write(base, TIMERCOUNT, 0);
356 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
358 nsp_index_write(base, SYNCREG, 0);
359 nsp_index_write(base, ACKWIDTH, 0);
361 /* enable interrupts and ack them */
362 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
363 RESELECT_EI |
364 SCSI_RESET_IRQ_EI );
365 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
367 nsp_setup_fifo(data, FALSE);
369 return TRUE;
373 * Start selection phase
375 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
377 unsigned int host_id = SCpnt->device->host->this_id;
378 unsigned int base = SCpnt->device->host->io_port;
379 unsigned char target = SCpnt->device->id;
380 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
381 int time_out;
382 unsigned char phase, arbit;
384 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
386 phase = nsp_index_read(base, SCSIBUSMON);
387 if(phase != BUSMON_BUS_FREE) {
388 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
389 return FALSE;
392 /* start arbitration */
393 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
394 SCpnt->SCp.phase = PH_ARBSTART;
395 nsp_index_write(base, SETARBIT, ARBIT_GO);
397 time_out = 1000;
398 do {
399 /* XXX: what a stupid chip! */
400 arbit = nsp_index_read(base, ARBITSTATUS);
401 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
402 udelay(1); /* hold 1.2us */
403 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
404 (time_out-- != 0));
406 if (!(arbit & ARBIT_WIN)) {
407 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
408 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
409 return FALSE;
412 /* assert select line */
413 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
414 SCpnt->SCp.phase = PH_SELSTART;
415 udelay(3); /* wait 2.4us */
416 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
417 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
418 udelay(2); /* wait >1.2us */
419 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
420 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
421 /*udelay(1);*/ /* wait >90ns */
422 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
424 /* check selection timeout */
425 nsp_start_timer(SCpnt, 1000/51);
426 data->SelectionTimeOut = 1;
428 return TRUE;
431 struct nsp_sync_table {
432 unsigned int min_period;
433 unsigned int max_period;
434 unsigned int chip_period;
435 unsigned int ack_width;
438 static struct nsp_sync_table nsp_sync_table_40M[] = {
439 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
440 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
441 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
442 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
443 { 0, 0, 0, 0},
446 static struct nsp_sync_table nsp_sync_table_20M[] = {
447 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
448 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
449 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
450 { 0, 0, 0, 0},
454 * setup synchronous data transfer mode
456 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
458 unsigned char target = SCpnt->device->id;
459 // unsigned char lun = SCpnt->device->lun;
460 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
461 sync_data *sync = &(data->Sync[target]);
462 struct nsp_sync_table *sync_table;
463 unsigned int period, offset;
464 int i;
467 nsp_dbg(NSP_DEBUG_SYNC, "in");
469 period = sync->SyncPeriod;
470 offset = sync->SyncOffset;
472 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
474 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
475 sync_table = nsp_sync_table_20M;
476 } else {
477 sync_table = nsp_sync_table_40M;
480 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
481 if ( period >= sync_table->min_period &&
482 period <= sync_table->max_period ) {
483 break;
487 if (period != 0 && sync_table->max_period == 0) {
489 * No proper period/offset found
491 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
493 sync->SyncPeriod = 0;
494 sync->SyncOffset = 0;
495 sync->SyncRegister = 0;
496 sync->AckWidth = 0;
498 return FALSE;
501 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
502 (offset & SYNCREG_OFFSET_MASK);
503 sync->AckWidth = sync_table->ack_width;
505 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
507 return TRUE;
512 * start ninja hardware timer
514 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
516 unsigned int base = SCpnt->device->host->io_port;
517 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
519 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
520 data->TimerCount = time;
521 nsp_index_write(base, TIMERCOUNT, time);
525 * wait for bus phase change
527 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
529 unsigned int base = SCpnt->device->host->io_port;
530 unsigned char reg;
531 int time_out;
533 //nsp_dbg(NSP_DEBUG_INTR, "in");
535 time_out = 100;
537 do {
538 reg = nsp_index_read(base, SCSIBUSMON);
539 if (reg == 0xff) {
540 break;
542 } while ((time_out-- != 0) && (reg & mask) != 0);
544 if (time_out == 0) {
545 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
548 return 0;
552 * expect Ninja Irq
554 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
555 unsigned char current_phase,
556 unsigned char mask)
558 unsigned int base = SCpnt->device->host->io_port;
559 int time_out;
560 unsigned char phase, i_src;
562 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
564 time_out = 100;
565 do {
566 phase = nsp_index_read(base, SCSIBUSMON);
567 if (phase == 0xff) {
568 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
569 return -1;
571 i_src = nsp_read(base, IRQSTATUS);
572 if (i_src & IRQSTATUS_SCSI) {
573 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
574 return 0;
576 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
577 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
578 return 1;
580 } while(time_out-- != 0);
582 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
583 return -1;
587 * transfer SCSI message
589 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
591 unsigned int base = SCpnt->device->host->io_port;
592 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
593 char *buf = data->MsgBuffer;
594 int len = min(MSGBUF_SIZE, data->MsgLen);
595 int ptr;
596 int ret;
598 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
599 for (ptr = 0; len > 0; len--, ptr++) {
601 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
602 if (ret <= 0) {
603 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
604 return 0;
607 /* if last byte, negate ATN */
608 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
609 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
612 /* read & write message */
613 if (phase & BUSMON_IO) {
614 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
615 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
616 } else {
617 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
618 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
620 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
623 return len;
627 * get extra SCSI data from fifo
629 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
631 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
632 unsigned int count;
634 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
636 if (SCpnt->SCp.have_data_in != IO_IN) {
637 return 0;
640 count = nsp_fifo_count(SCpnt);
641 if (data->FifoCount == count) {
642 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
643 return 0;
647 * XXX: NSP_QUIRK
648 * data phase skip only occures in case of SCSI_LOW_READ
650 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
651 SCpnt->SCp.phase = PH_DATA;
652 nsp_pio_read(SCpnt);
653 nsp_setup_fifo(data, FALSE);
655 return 0;
659 * accept reselection
661 static int nsp_reselected(Scsi_Cmnd *SCpnt)
663 unsigned int base = SCpnt->device->host->io_port;
664 unsigned int host_id = SCpnt->device->host->this_id;
665 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
666 unsigned char bus_reg;
667 unsigned char id_reg, tmp;
668 int target;
670 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
672 id_reg = nsp_index_read(base, RESELECTID);
673 tmp = id_reg & (~BIT(host_id));
674 target = 0;
675 while(tmp != 0) {
676 if (tmp & BIT(0)) {
677 break;
679 tmp >>= 1;
680 target++;
683 if (SCpnt->device->id != target) {
684 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
687 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
689 nsp_nexus(SCpnt);
690 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
691 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
692 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
694 return TRUE;
698 * count how many data transferd
700 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
702 unsigned int base = SCpnt->device->host->io_port;
703 unsigned int count;
704 unsigned int l, m, h, dummy;
706 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
708 l = nsp_index_read(base, TRANSFERCOUNT);
709 m = nsp_index_read(base, TRANSFERCOUNT);
710 h = nsp_index_read(base, TRANSFERCOUNT);
711 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
713 count = (h << 16) | (m << 8) | (l << 0);
715 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
717 return count;
720 /* fifo size */
721 #define RFIFO_CRIT 64
722 #define WFIFO_CRIT 64
725 * read data in DATA IN phase
727 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
729 unsigned int base = SCpnt->device->host->io_port;
730 unsigned long mmio_base = SCpnt->device->host->base;
731 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
732 long time_out;
733 int ocount, res;
734 unsigned char stat, fifo_stat;
736 ocount = data->FifoCount;
738 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",
739 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
741 time_out = 1000;
743 while ((time_out-- != 0) &&
744 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
746 stat = nsp_index_read(base, SCSIBUSMON);
747 stat &= BUSMON_PHASE_MASK;
750 res = nsp_fifo_count(SCpnt) - ocount;
751 //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);
752 if (res == 0) { /* if some data avilable ? */
753 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
754 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
755 continue;
756 } else {
757 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
758 break;
762 fifo_stat = nsp_read(base, FIFOSTATUS);
763 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
764 stat == BUSPHASE_DATA_IN) {
765 continue;
768 res = min(res, SCpnt->SCp.this_residual);
770 switch (data->TransferMode) {
771 case MODE_IO32:
772 res &= ~(BIT(1)|BIT(0)); /* align 4 */
773 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
774 break;
775 case MODE_IO8:
776 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
777 break;
779 case MODE_MEM32:
780 res &= ~(BIT(1)|BIT(0)); /* align 4 */
781 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
782 break;
784 default:
785 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
786 return;
789 SCpnt->resid -= res;
790 SCpnt->SCp.ptr += res;
791 SCpnt->SCp.this_residual -= res;
792 ocount += res;
793 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
795 /* go to next scatter list if available */
796 if (SCpnt->SCp.this_residual == 0 &&
797 SCpnt->SCp.buffers_residual != 0 ) {
798 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
799 SCpnt->SCp.buffers_residual--;
800 SCpnt->SCp.buffer++;
801 SCpnt->SCp.ptr = BUFFER_ADDR;
802 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
803 time_out = 1000;
805 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
809 data->FifoCount = ocount;
811 if (time_out == 0) {
812 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
813 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
815 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
816 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
820 * write data in DATA OUT phase
822 static void nsp_pio_write(Scsi_Cmnd *SCpnt)
824 unsigned int base = SCpnt->device->host->io_port;
825 unsigned long mmio_base = SCpnt->device->host->base;
826 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
827 int time_out;
828 int ocount, res;
829 unsigned char stat;
831 ocount = data->FifoCount;
833 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
834 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
836 time_out = 1000;
838 while ((time_out-- != 0) &&
839 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
840 stat = nsp_index_read(base, SCSIBUSMON);
841 stat &= BUSMON_PHASE_MASK;
843 if (stat != BUSPHASE_DATA_OUT) {
844 res = ocount - nsp_fifo_count(SCpnt);
846 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
847 /* Put back pointer */
848 SCpnt->resid += res;
849 SCpnt->SCp.ptr -= res;
850 SCpnt->SCp.this_residual += res;
851 ocount -= res;
853 break;
856 res = ocount - nsp_fifo_count(SCpnt);
857 if (res > 0) { /* write all data? */
858 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
859 continue;
862 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
864 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
865 switch (data->TransferMode) {
866 case MODE_IO32:
867 res &= ~(BIT(1)|BIT(0)); /* align 4 */
868 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
869 break;
870 case MODE_IO8:
871 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
872 break;
874 case MODE_MEM32:
875 res &= ~(BIT(1)|BIT(0)); /* align 4 */
876 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
877 break;
879 default:
880 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
881 break;
884 SCpnt->resid -= res;
885 SCpnt->SCp.ptr += res;
886 SCpnt->SCp.this_residual -= res;
887 ocount += res;
889 /* go to next scatter list if available */
890 if (SCpnt->SCp.this_residual == 0 &&
891 SCpnt->SCp.buffers_residual != 0 ) {
892 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
893 SCpnt->SCp.buffers_residual--;
894 SCpnt->SCp.buffer++;
895 SCpnt->SCp.ptr = BUFFER_ADDR;
896 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
897 time_out = 1000;
901 data->FifoCount = ocount;
903 if (time_out == 0) {
904 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
906 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
907 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
909 #undef RFIFO_CRIT
910 #undef WFIFO_CRIT
913 * setup synchronous/asynchronous data transfer mode
915 static int nsp_nexus(Scsi_Cmnd *SCpnt)
917 unsigned int base = SCpnt->device->host->io_port;
918 unsigned char target = SCpnt->device->id;
919 // unsigned char lun = SCpnt->device->lun;
920 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
921 sync_data *sync = &(data->Sync[target]);
923 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
925 /* setup synch transfer registers */
926 nsp_index_write(base, SYNCREG, sync->SyncRegister);
927 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
929 if (SCpnt->use_sg == 0 ||
930 SCpnt->resid % 4 != 0 ||
931 SCpnt->resid <= PAGE_SIZE ) {
932 data->TransferMode = MODE_IO8;
933 } else if (nsp_burst_mode == BURST_MEM32) {
934 data->TransferMode = MODE_MEM32;
935 } else if (nsp_burst_mode == BURST_IO32) {
936 data->TransferMode = MODE_IO32;
937 } else {
938 data->TransferMode = MODE_IO8;
941 /* setup pdma fifo */
942 nsp_setup_fifo(data, TRUE);
944 /* clear ack counter */
945 data->FifoCount = 0;
946 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
947 ACK_COUNTER_CLEAR |
948 REQ_COUNTER_CLEAR |
949 HOST_COUNTER_CLEAR);
951 return 0;
954 #include "nsp_message.c"
956 * interrupt handler
958 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
960 unsigned int base;
961 unsigned char irq_status, irq_phase, phase;
962 Scsi_Cmnd *tmpSC;
963 unsigned char target, lun;
964 unsigned int *sync_neg;
965 int i, tmp;
966 nsp_hw_data *data;
969 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
970 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
972 if ( dev_id != NULL &&
973 ((scsi_info_t *)dev_id)->host != NULL ) {
974 scsi_info_t *info = (scsi_info_t *)dev_id;
976 data = (nsp_hw_data *)info->host->hostdata;
977 } else {
978 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
979 return IRQ_NONE;
982 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
984 base = data->BaseAddress;
985 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
988 * interrupt check
990 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
991 irq_status = nsp_read(base, IRQSTATUS);
992 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
993 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
994 nsp_write(base, IRQCONTROL, 0);
995 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
996 return IRQ_NONE;
999 /* XXX: IMPORTANT
1000 * Do not read an irq_phase register if no scsi phase interrupt.
1001 * Unless, you should lose a scsi phase interrupt.
1003 phase = nsp_index_read(base, SCSIBUSMON);
1004 if((irq_status & IRQSTATUS_SCSI) != 0) {
1005 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1006 } else {
1007 irq_phase = 0;
1010 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1013 * timer interrupt handler (scsi vs timer interrupts)
1015 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1016 if (data->TimerCount != 0) {
1017 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1018 nsp_index_write(base, TIMERCOUNT, 0);
1019 nsp_index_write(base, TIMERCOUNT, 0);
1020 data->TimerCount = 0;
1023 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1024 data->SelectionTimeOut == 0) {
1025 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1026 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1027 return IRQ_HANDLED;
1030 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1032 if ((irq_status & IRQSTATUS_SCSI) &&
1033 (irq_phase & SCSI_RESET_IRQ)) {
1034 nsp_msg(KERN_ERR, "bus reset (power off?)");
1036 nsphw_init(data);
1037 nsp_bus_reset(data);
1039 if(data->CurrentSC != NULL) {
1040 tmpSC = data->CurrentSC;
1041 tmpSC->result = (DID_RESET << 16) |
1042 ((tmpSC->SCp.Message & 0xff) << 8) |
1043 ((tmpSC->SCp.Status & 0xff) << 0);
1044 nsp_scsi_done(tmpSC);
1046 return IRQ_HANDLED;
1049 if (data->CurrentSC == NULL) {
1050 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);
1051 nsphw_init(data);
1052 nsp_bus_reset(data);
1053 return IRQ_HANDLED;
1056 tmpSC = data->CurrentSC;
1057 target = tmpSC->device->id;
1058 lun = tmpSC->device->lun;
1059 sync_neg = &(data->Sync[target].SyncNegotiation);
1062 * parse hardware SCSI irq reasons register
1064 if (irq_status & IRQSTATUS_SCSI) {
1065 if (irq_phase & RESELECT_IRQ) {
1066 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1067 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1068 if (nsp_reselected(tmpSC) != FALSE) {
1069 return IRQ_HANDLED;
1073 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1074 return IRQ_HANDLED;
1078 //show_phase(tmpSC);
1080 switch(tmpSC->SCp.phase) {
1081 case PH_SELSTART:
1082 // *sync_neg = SYNC_NOT_YET;
1083 if ((phase & BUSMON_BSY) == 0) {
1084 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1085 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1086 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1087 data->SelectionTimeOut = 0;
1088 nsp_index_write(base, SCSIBUSCTRL, 0);
1090 tmpSC->result = DID_TIME_OUT << 16;
1091 nsp_scsi_done(tmpSC);
1093 return IRQ_HANDLED;
1095 data->SelectionTimeOut += 1;
1096 nsp_start_timer(tmpSC, 1000/51);
1097 return IRQ_HANDLED;
1100 /* attention assert */
1101 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1102 data->SelectionTimeOut = 0;
1103 tmpSC->SCp.phase = PH_SELECTED;
1104 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1105 udelay(1);
1106 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1107 return IRQ_HANDLED;
1109 break;
1111 case PH_RESELECT:
1112 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1113 // *sync_neg = SYNC_NOT_YET;
1114 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1116 tmpSC->result = DID_ABORT << 16;
1117 nsp_scsi_done(tmpSC);
1118 return IRQ_HANDLED;
1120 /* fall thru */
1121 default:
1122 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1123 return IRQ_HANDLED;
1125 break;
1129 * SCSI sequencer
1131 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1133 /* normal disconnect */
1134 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1135 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1136 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1138 //*sync_neg = SYNC_NOT_YET;
1140 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1141 tmpSC->result = (DID_OK << 16) |
1142 ((tmpSC->SCp.Message & 0xff) << 8) |
1143 ((tmpSC->SCp.Status & 0xff) << 0);
1144 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1145 nsp_scsi_done(tmpSC);
1147 return IRQ_HANDLED;
1150 return IRQ_HANDLED;
1154 /* check unexpected bus free state */
1155 if (phase == 0) {
1156 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1158 *sync_neg = SYNC_NG;
1159 tmpSC->result = DID_ERROR << 16;
1160 nsp_scsi_done(tmpSC);
1161 return IRQ_HANDLED;
1164 switch (phase & BUSMON_PHASE_MASK) {
1165 case BUSPHASE_COMMAND:
1166 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1167 if ((phase & BUSMON_REQ) == 0) {
1168 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1169 return IRQ_HANDLED;
1172 tmpSC->SCp.phase = PH_COMMAND;
1174 nsp_nexus(tmpSC);
1176 /* write scsi command */
1177 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1178 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1179 for (i = 0; i < tmpSC->cmd_len; i++) {
1180 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1182 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1183 break;
1185 case BUSPHASE_DATA_OUT:
1186 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1188 tmpSC->SCp.phase = PH_DATA;
1189 tmpSC->SCp.have_data_in = IO_OUT;
1191 nsp_pio_write(tmpSC);
1193 break;
1195 case BUSPHASE_DATA_IN:
1196 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1198 tmpSC->SCp.phase = PH_DATA;
1199 tmpSC->SCp.have_data_in = IO_IN;
1201 nsp_pio_read(tmpSC);
1203 break;
1205 case BUSPHASE_STATUS:
1206 nsp_dataphase_bypass(tmpSC);
1207 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1209 tmpSC->SCp.phase = PH_STATUS;
1211 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1212 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1214 break;
1216 case BUSPHASE_MESSAGE_OUT:
1217 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1218 if ((phase & BUSMON_REQ) == 0) {
1219 goto timer_out;
1222 tmpSC->SCp.phase = PH_MSG_OUT;
1224 //*sync_neg = SYNC_NOT_YET;
1226 data->MsgLen = i = 0;
1227 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1229 if (*sync_neg == SYNC_NOT_YET) {
1230 data->Sync[target].SyncPeriod = 0;
1231 data->Sync[target].SyncOffset = 0;
1233 /**/
1234 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1235 data->MsgBuffer[i] = 3; i++;
1236 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1237 data->MsgBuffer[i] = 0x0c; i++;
1238 data->MsgBuffer[i] = 15; i++;
1239 /**/
1241 data->MsgLen = i;
1243 nsp_analyze_sdtr(tmpSC);
1244 show_message(data);
1245 nsp_message_out(tmpSC);
1246 break;
1248 case BUSPHASE_MESSAGE_IN:
1249 nsp_dataphase_bypass(tmpSC);
1250 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1251 if ((phase & BUSMON_REQ) == 0) {
1252 goto timer_out;
1255 tmpSC->SCp.phase = PH_MSG_IN;
1256 nsp_message_in(tmpSC);
1258 /**/
1259 if (*sync_neg == SYNC_NOT_YET) {
1260 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1262 if (data->MsgLen >= 5 &&
1263 data->MsgBuffer[0] == MSG_EXTENDED &&
1264 data->MsgBuffer[1] == 3 &&
1265 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1266 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1267 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1268 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1269 *sync_neg = SYNC_OK;
1270 } else {
1271 data->Sync[target].SyncPeriod = 0;
1272 data->Sync[target].SyncOffset = 0;
1273 *sync_neg = SYNC_NG;
1275 nsp_analyze_sdtr(tmpSC);
1277 /**/
1279 /* search last messeage byte */
1280 tmp = -1;
1281 for (i = 0; i < data->MsgLen; i++) {
1282 tmp = data->MsgBuffer[i];
1283 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1284 i += (1 + data->MsgBuffer[i+1]);
1287 tmpSC->SCp.Message = tmp;
1289 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1290 show_message(data);
1292 break;
1294 case BUSPHASE_SELECT:
1295 default:
1296 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1298 break;
1301 //nsp_dbg(NSP_DEBUG_INTR, "out");
1302 return IRQ_HANDLED;
1304 timer_out:
1305 nsp_start_timer(tmpSC, 1000/102);
1306 return IRQ_HANDLED;
1309 #ifdef NSP_DEBUG
1310 #include "nsp_debug.c"
1311 #endif /* NSP_DEBUG */
1313 /*----------------------------------------------------------------*/
1314 /* look for ninja3 card and init if found */
1315 /*----------------------------------------------------------------*/
1316 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
1318 struct Scsi_Host *host; /* registered host structure */
1319 nsp_hw_data *data_b = &nsp_data_base, *data;
1321 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1322 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1323 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1324 #else
1325 host = scsi_register(sht, sizeof(nsp_hw_data));
1326 #endif
1327 if (host == NULL) {
1328 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1329 return NULL;
1332 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1333 data = (nsp_hw_data *)host->hostdata;
1334 data->ScsiInfo->host = host;
1335 #ifdef NSP_DEBUG
1336 data->CmdId = 0;
1337 #endif
1339 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1341 host->unique_id = data->BaseAddress;
1342 host->io_port = data->BaseAddress;
1343 host->n_io_port = data->NumAddress;
1344 host->irq = data->IrqNumber;
1345 host->base = data->MmioAddress;
1347 spin_lock_init(&(data->Lock));
1349 snprintf(data->nspinfo,
1350 sizeof(data->nspinfo),
1351 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1352 host->io_port, host->io_port + host->n_io_port - 1,
1353 host->base,
1354 host->irq);
1355 sht->name = data->nspinfo;
1357 nsp_dbg(NSP_DEBUG_INIT, "end");
1360 return host; /* detect done. */
1363 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1364 static int nsp_detect_old(Scsi_Host_Template *sht)
1366 if (nsp_detect(sht) == NULL) {
1367 return 0;
1368 } else {
1369 //MOD_INC_USE_COUNT;
1370 return 1;
1375 static int nsp_release_old(struct Scsi_Host *shpnt)
1377 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1379 /* PCMCIA Card Service dose same things below. */
1380 /* So we do nothing. */
1381 //if (shpnt->irq) {
1382 // free_irq(shpnt->irq, data->ScsiInfo);
1384 //if (shpnt->io_port) {
1385 // release_region(shpnt->io_port, shpnt->n_io_port);
1388 //MOD_DEC_USE_COUNT;
1390 return 0;
1392 #endif
1394 /*----------------------------------------------------------------*/
1395 /* return info string */
1396 /*----------------------------------------------------------------*/
1397 static const char *nsp_info(struct Scsi_Host *shpnt)
1399 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1401 return data->nspinfo;
1404 #undef SPRINTF
1405 #define SPRINTF(args...) \
1406 do { \
1407 if(length > (pos - buffer)) { \
1408 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1409 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1411 } while(0)
1412 static int
1413 nsp_proc_info(
1414 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1415 struct Scsi_Host *host,
1416 #endif
1417 char *buffer,
1418 char **start,
1419 off_t offset,
1420 int length,
1421 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1422 int hostno,
1423 #endif
1424 int inout)
1426 int id;
1427 char *pos = buffer;
1428 int thislength;
1429 int speed;
1430 unsigned long flags;
1431 nsp_hw_data *data;
1432 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1433 struct Scsi_Host *host;
1434 #else
1435 int hostno;
1436 #endif
1437 if (inout) {
1438 return -EINVAL;
1441 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1442 hostno = host->host_no;
1443 #else
1444 /* search this HBA host */
1445 host = scsi_host_hn_get(hostno);
1446 if (host == NULL) {
1447 return -ESRCH;
1449 #endif
1450 data = (nsp_hw_data *)host->hostdata;
1453 SPRINTF("NinjaSCSI status\n\n");
1454 SPRINTF("Driver version: $Revision: 1.23 $\n");
1455 SPRINTF("SCSI host No.: %d\n", hostno);
1456 SPRINTF("IRQ: %d\n", host->irq);
1457 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1458 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1459 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1461 SPRINTF("burst transfer mode: ");
1462 switch (nsp_burst_mode) {
1463 case BURST_IO8:
1464 SPRINTF("io8");
1465 break;
1466 case BURST_IO32:
1467 SPRINTF("io32");
1468 break;
1469 case BURST_MEM32:
1470 SPRINTF("mem32");
1471 break;
1472 default:
1473 SPRINTF("???");
1474 break;
1476 SPRINTF("\n");
1479 spin_lock_irqsave(&(data->Lock), flags);
1480 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1481 spin_unlock_irqrestore(&(data->Lock), flags);
1483 SPRINTF("SDTR status\n");
1484 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1486 SPRINTF("id %d: ", id);
1488 if (id == host->this_id) {
1489 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1490 continue;
1493 switch(data->Sync[id].SyncNegotiation) {
1494 case SYNC_OK:
1495 SPRINTF(" sync");
1496 break;
1497 case SYNC_NG:
1498 SPRINTF("async");
1499 break;
1500 case SYNC_NOT_YET:
1501 SPRINTF(" none");
1502 break;
1503 default:
1504 SPRINTF("?????");
1505 break;
1508 if (data->Sync[id].SyncPeriod != 0) {
1509 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1511 SPRINTF(" transfer %d.%dMB/s, offset %d",
1512 speed / 1000,
1513 speed % 1000,
1514 data->Sync[id].SyncOffset
1517 SPRINTF("\n");
1520 thislength = pos - (buffer + offset);
1522 if(thislength < 0) {
1523 *start = NULL;
1524 return 0;
1528 thislength = min(thislength, length);
1529 *start = buffer + offset;
1531 return thislength;
1533 #undef SPRINTF
1535 /*---------------------------------------------------------------*/
1536 /* error handler */
1537 /*---------------------------------------------------------------*/
1539 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
1541 return FAILED;
1545 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1547 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1549 return nsp_eh_bus_reset(SCpnt);
1553 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
1555 nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
1557 return FAILED;
1560 static int nsp_bus_reset(nsp_hw_data *data)
1562 unsigned int base = data->BaseAddress;
1563 int i;
1565 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1567 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1568 mdelay(100); /* 100ms */
1569 nsp_index_write(base, SCSIBUSCTRL, 0);
1570 for(i = 0; i < 5; i++) {
1571 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1574 nsphw_init_sync(data);
1576 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1578 return SUCCESS;
1581 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1583 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1585 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1587 return nsp_bus_reset(data);
1590 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1592 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1594 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1596 nsphw_init(data);
1598 return SUCCESS;
1602 /**********************************************************************
1603 PCMCIA functions
1604 **********************************************************************/
1606 /*======================================================================
1607 nsp_cs_attach() creates an "instance" of the driver, allocating
1608 local data structures for one device. The device is registered
1609 with Card Services.
1611 The dev_link structure is initialized, but we don't actually
1612 configure the card at this point -- we wait until we receive a
1613 card insertion event.
1614 ======================================================================*/
1615 static dev_link_t *nsp_cs_attach(void)
1617 scsi_info_t *info;
1618 client_reg_t client_reg;
1619 dev_link_t *link;
1620 int ret;
1621 nsp_hw_data *data = &nsp_data_base;
1623 nsp_dbg(NSP_DEBUG_INIT, "in");
1625 /* Create new SCSI device */
1626 info = kmalloc(sizeof(*info), GFP_KERNEL);
1627 if (info == NULL) { return NULL; }
1628 memset(info, 0, sizeof(*info));
1629 link = &info->link;
1630 link->priv = info;
1631 data->ScsiInfo = info;
1633 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1635 /* The io structure describes IO port mapping */
1636 link->io.NumPorts1 = 0x10;
1637 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1638 link->io.IOAddrLines = 10; /* not used */
1640 /* Interrupt setup */
1641 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1642 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1644 /* Interrupt handler */
1645 link->irq.Handler = &nspintr;
1646 link->irq.Instance = info;
1647 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1649 /* General socket configuration */
1650 link->conf.Attributes = CONF_ENABLE_IRQ;
1651 link->conf.Vcc = 50;
1652 link->conf.IntType = INT_MEMORY_AND_IO;
1653 link->conf.Present = PRESENT_OPTION;
1656 /* Register with Card Services */
1657 link->next = dev_list;
1658 dev_list = link;
1659 client_reg.dev_info = &dev_info;
1660 client_reg.EventMask =
1661 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1662 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1663 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1664 client_reg.event_handler = &nsp_cs_event;
1665 client_reg.Version = 0x0210;
1666 client_reg.event_callback_args.client_data = link;
1667 ret = pcmcia_register_client(&link->handle, &client_reg);
1668 if (ret != CS_SUCCESS) {
1669 cs_error(link->handle, RegisterClient, ret);
1670 nsp_cs_detach(link);
1671 return NULL;
1675 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1676 return link;
1677 } /* nsp_cs_attach */
1680 /*======================================================================
1681 This deletes a driver "instance". The device is de-registered
1682 with Card Services. If it has been released, all local data
1683 structures are freed. Otherwise, the structures will be freed
1684 when the device is released.
1685 ======================================================================*/
1686 static void nsp_cs_detach(dev_link_t *link)
1688 dev_link_t **linkp;
1690 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1692 /* Locate device structure */
1693 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1694 if (*linkp == link) {
1695 break;
1698 if (*linkp == NULL) {
1699 return;
1702 if (link->state & DEV_CONFIG)
1703 nsp_cs_release(link);
1705 /* Break the link with Card Services */
1706 if (link->handle) {
1707 pcmcia_deregister_client(link->handle);
1710 /* Unlink device structure, free bits */
1711 *linkp = link->next;
1712 kfree(link->priv);
1713 link->priv = NULL;
1715 } /* nsp_cs_detach */
1718 /*======================================================================
1719 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1720 is received, to configure the PCMCIA socket, and to make the
1721 ethernet device available to the system.
1722 ======================================================================*/
1723 #define CS_CHECK(fn, ret) \
1724 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1725 /*====================================================================*/
1726 static void nsp_cs_config(dev_link_t *link)
1728 client_handle_t handle = link->handle;
1729 scsi_info_t *info = link->priv;
1730 tuple_t tuple;
1731 cisparse_t parse;
1732 int last_ret, last_fn;
1733 unsigned char tuple_data[64];
1734 config_info_t conf;
1735 win_req_t req;
1736 memreq_t map;
1737 cistpl_cftable_entry_t dflt = { 0 };
1738 struct Scsi_Host *host;
1739 nsp_hw_data *data = &nsp_data_base;
1740 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1741 Scsi_Device *dev;
1742 dev_node_t **tail, *node;
1743 #endif
1745 nsp_dbg(NSP_DEBUG_INIT, "in");
1747 tuple.DesiredTuple = CISTPL_CONFIG;
1748 tuple.Attributes = 0;
1749 tuple.TupleData = tuple_data;
1750 tuple.TupleDataMax = sizeof(tuple_data);
1751 tuple.TupleOffset = 0;
1752 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1753 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1754 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1755 link->conf.ConfigBase = parse.config.base;
1756 link->conf.Present = parse.config.rmask[0];
1758 /* Configure card */
1759 link->state |= DEV_CONFIG;
1761 /* Look up the current Vcc */
1762 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1763 link->conf.Vcc = conf.Vcc;
1765 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1766 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1767 while (1) {
1768 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1770 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1771 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1772 goto next_entry;
1774 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1775 if (cfg->index == 0) { goto next_entry; }
1776 link->conf.ConfigIndex = cfg->index;
1778 /* Does this card need audio output? */
1779 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1780 link->conf.Attributes |= CONF_ENABLE_SPKR;
1781 link->conf.Status = CCSR_AUDIO_ENA;
1784 /* Use power settings for Vcc and Vpp if present */
1785 /* Note that the CIS values need to be rescaled */
1786 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1787 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1788 goto next_entry;
1790 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1791 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1792 goto next_entry;
1796 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1797 link->conf.Vpp1 = link->conf.Vpp2 =
1798 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1799 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1800 link->conf.Vpp1 = link->conf.Vpp2 =
1801 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1804 /* Do we need to allocate an interrupt? */
1805 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1806 link->conf.Attributes |= CONF_ENABLE_IRQ;
1809 /* IO window settings */
1810 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1811 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1812 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1813 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1814 if (!(io->flags & CISTPL_IO_8BIT))
1815 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1816 if (!(io->flags & CISTPL_IO_16BIT))
1817 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1818 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1819 link->io.BasePort1 = io->win[0].base;
1820 link->io.NumPorts1 = io->win[0].len;
1821 if (io->nwin > 1) {
1822 link->io.Attributes2 = link->io.Attributes1;
1823 link->io.BasePort2 = io->win[1].base;
1824 link->io.NumPorts2 = io->win[1].len;
1826 /* This reserves IO space but doesn't actually enable it */
1827 if (pcmcia_request_io(link->handle, &link->io) != 0)
1828 goto next_entry;
1831 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1832 cistpl_mem_t *mem =
1833 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1834 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1835 req.Attributes |= WIN_ENABLE;
1836 req.Base = mem->win[0].host_addr;
1837 req.Size = mem->win[0].len;
1838 if (req.Size < 0x1000) {
1839 req.Size = 0x1000;
1841 req.AccessSpeed = 0;
1842 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1843 goto next_entry;
1844 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1845 if (pcmcia_map_mem_page(link->win, &map) != 0)
1846 goto next_entry;
1848 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1849 data->MmioLength = req.Size;
1851 /* If we got this far, we're cool! */
1852 break;
1854 next_entry:
1855 nsp_dbg(NSP_DEBUG_INIT, "next");
1857 if (link->io.NumPorts1) {
1858 pcmcia_release_io(link->handle, &link->io);
1860 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1863 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1864 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1866 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1868 if (free_ports) {
1869 if (link->io.BasePort1) {
1870 release_region(link->io.BasePort1, link->io.NumPorts1);
1872 if (link->io.BasePort2) {
1873 release_region(link->io.BasePort2, link->io.NumPorts2);
1877 /* Set port and IRQ */
1878 data->BaseAddress = link->io.BasePort1;
1879 data->NumAddress = link->io.NumPorts1;
1880 data->IrqNumber = link->irq.AssignedIRQ;
1882 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1883 data->BaseAddress, data->NumAddress, data->IrqNumber);
1885 if(nsphw_init(data) == FALSE) {
1886 goto cs_failed;
1889 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1890 host = nsp_detect(&nsp_driver_template);
1891 #else
1892 scsi_register_host(&nsp_driver_template);
1893 for (host = scsi_host_get_next(NULL); host != NULL;
1894 host = scsi_host_get_next(host)) {
1895 if (host->hostt == &nsp_driver_template) {
1896 break;
1899 #endif
1901 if (host == NULL) {
1902 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1903 goto cs_failed;
1907 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1908 scsi_add_host (host, NULL);
1909 scsi_scan_host(host);
1911 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1912 link->dev = &info->node;
1913 info->host = host;
1915 #else
1916 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1917 tail = &link->dev;
1918 info->ndev = 0;
1920 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1922 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1923 unsigned long id;
1924 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1925 ((dev->channel & 0x0f) << 8) +
1926 ((dev->host->host_no & 0x0f) << 12);
1927 node = &info->node[info->ndev];
1928 node->minor = 0;
1929 switch (dev->type) {
1930 case TYPE_TAPE:
1931 node->major = SCSI_TAPE_MAJOR;
1932 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1933 break;
1934 case TYPE_DISK:
1935 case TYPE_MOD:
1936 node->major = SCSI_DISK0_MAJOR;
1937 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1938 break;
1939 case TYPE_ROM:
1940 case TYPE_WORM:
1941 node->major = SCSI_CDROM_MAJOR;
1942 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1943 break;
1944 default:
1945 node->major = SCSI_GENERIC_MAJOR;
1946 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1947 break;
1949 *tail = node; tail = &node->next;
1950 info->ndev++;
1951 info->host = dev->host;
1954 *tail = NULL;
1955 if (info->ndev == 0) {
1956 nsp_msg(KERN_INFO, "no SCSI devices found");
1958 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1959 #endif
1961 /* Finally, report what we've done */
1962 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1963 link->conf.ConfigIndex,
1964 link->conf.Vcc/10, link->conf.Vcc%10);
1965 if (link->conf.Vpp1) {
1966 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1968 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1969 printk(", irq %d", link->irq.AssignedIRQ);
1971 if (link->io.NumPorts1) {
1972 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1973 link->io.BasePort1+link->io.NumPorts1-1);
1975 if (link->io.NumPorts2)
1976 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1977 link->io.BasePort2+link->io.NumPorts2-1);
1978 if (link->win)
1979 printk(", mem 0x%06lx-0x%06lx", req.Base,
1980 req.Base+req.Size-1);
1981 printk("\n");
1983 link->state &= ~DEV_CONFIG_PENDING;
1984 return;
1986 cs_failed:
1987 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1988 cs_error(link->handle, last_fn, last_ret);
1989 nsp_cs_release(link);
1991 return;
1992 } /* nsp_cs_config */
1993 #undef CS_CHECK
1996 /*======================================================================
1997 After a card is removed, nsp_cs_release() will unregister the net
1998 device, and release the PCMCIA configuration. If the device is
1999 still open, this will be postponed until it is closed.
2000 ======================================================================*/
2001 static void nsp_cs_release(dev_link_t *link)
2003 scsi_info_t *info = link->priv;
2004 nsp_hw_data *data = NULL;
2006 if (info->host == NULL) {
2007 nsp_msg(KERN_DEBUG, "unexpected card release call.");
2008 } else {
2009 data = (nsp_hw_data *)info->host->hostdata;
2012 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
2014 /* Unlink the device chain */
2015 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2016 if (info->host != NULL) {
2017 scsi_remove_host(info->host);
2019 #else
2020 scsi_unregister_host(&nsp_driver_template);
2021 #endif
2022 link->dev = NULL;
2024 if (link->win) {
2025 if (data != NULL) {
2026 iounmap((void *)(data->MmioAddress));
2028 pcmcia_release_window(link->win);
2030 pcmcia_release_configuration(link->handle);
2031 if (link->io.NumPorts1) {
2032 pcmcia_release_io(link->handle, &link->io);
2034 if (link->irq.AssignedIRQ) {
2035 pcmcia_release_irq(link->handle, &link->irq);
2037 link->state &= ~DEV_CONFIG;
2038 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2039 if (info->host != NULL) {
2040 scsi_host_put(info->host);
2042 #endif
2043 } /* nsp_cs_release */
2045 /*======================================================================
2047 The card status event handler. Mostly, this schedules other
2048 stuff to run after an event is received. A CARD_REMOVAL event
2049 also sets some flags to discourage the net drivers from trying
2050 to talk to the card any more.
2052 When a CARD_REMOVAL event is received, we immediately set a flag
2053 to block future accesses to this device. All the functions that
2054 actually access the device should check this flag to make sure
2055 the card is still present.
2057 ======================================================================*/
2058 static int nsp_cs_event(event_t event,
2059 int priority,
2060 event_callback_args_t *args)
2062 dev_link_t *link = args->client_data;
2063 scsi_info_t *info = link->priv;
2064 nsp_hw_data *data;
2066 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2068 switch (event) {
2069 case CS_EVENT_CARD_REMOVAL:
2070 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2071 link->state &= ~DEV_PRESENT;
2072 if (link->state & DEV_CONFIG) {
2073 ((scsi_info_t *)link->priv)->stop = 1;
2074 nsp_cs_release(link);
2076 break;
2078 case CS_EVENT_CARD_INSERTION:
2079 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2080 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2081 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2082 info->bus = args->bus;
2083 #endif
2084 nsp_cs_config(link);
2085 break;
2087 case CS_EVENT_PM_SUSPEND:
2088 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2089 link->state |= DEV_SUSPEND;
2090 /* Fall through... */
2091 case CS_EVENT_RESET_PHYSICAL:
2092 /* Mark the device as stopped, to block IO until later */
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2095 if (info->host != NULL) {
2096 nsp_msg(KERN_INFO, "clear SDTR status");
2098 data = (nsp_hw_data *)info->host->hostdata;
2100 nsphw_init_sync(data);
2103 info->stop = 1;
2104 if (link->state & DEV_CONFIG) {
2105 pcmcia_release_configuration(link->handle);
2107 break;
2109 case CS_EVENT_PM_RESUME:
2110 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2111 link->state &= ~DEV_SUSPEND;
2112 /* Fall through... */
2113 case CS_EVENT_CARD_RESET:
2114 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2115 if (link->state & DEV_CONFIG) {
2116 pcmcia_request_configuration(link->handle, &link->conf);
2118 info->stop = 0;
2120 if (info->host != NULL) {
2121 nsp_msg(KERN_INFO, "reset host and bus");
2123 data = (nsp_hw_data *)info->host->hostdata;
2125 nsphw_init (data);
2126 nsp_bus_reset(data);
2129 break;
2131 default:
2132 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2133 break;
2135 nsp_dbg(NSP_DEBUG_INIT, "end");
2136 return 0;
2137 } /* nsp_cs_event */
2139 /*======================================================================*
2140 * module entry point
2141 *====================================================================*/
2142 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2143 static struct pcmcia_driver nsp_driver = {
2144 .owner = THIS_MODULE,
2145 .drv = {
2146 .name = "nsp_cs",
2148 .attach = nsp_cs_attach,
2149 .detach = nsp_cs_detach,
2151 #endif
2153 static int __init nsp_cs_init(void)
2155 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2156 nsp_msg(KERN_INFO, "loading...");
2158 return pcmcia_register_driver(&nsp_driver);
2159 #else
2160 servinfo_t serv;
2162 nsp_msg(KERN_INFO, "loading...");
2163 pcmcia_get_card_services_info(&serv);
2164 if (serv.Revision != CS_RELEASE_CODE) {
2165 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2166 return -EINVAL;
2168 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2170 nsp_dbg(NSP_DEBUG_INIT, "out");
2171 return 0;
2172 #endif
2175 static void __exit nsp_cs_exit(void)
2177 nsp_msg(KERN_INFO, "unloading...");
2179 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2180 pcmcia_unregister_driver(&nsp_driver);
2181 BUG_ON(dev_list != NULL);
2182 #else
2183 unregister_pcmcia_driver(&dev_info);
2184 /* XXX: this really needs to move into generic code.. */
2185 while (dev_list != NULL) {
2186 if (dev_list->state & DEV_CONFIG) {
2187 nsp_cs_release(dev_list);
2189 nsp_cs_detach(dev_list);
2191 #endif
2195 module_init(nsp_cs_init)
2196 module_exit(nsp_cs_exit)
2198 /* end */