initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / scsi / pcmcia / nsp_cs.c
blob75648dcb6843b48b57e0d341e356535303978ab9
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 unsigned int irq_mask = 0xffff;
76 MODULE_PARM (irq_mask, "i");
77 MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
79 static int irq_list[4] = { -1 };
80 MODULE_PARM (irq_list, "1-4i");
81 MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
83 static int nsp_burst_mode = BURST_MEM32;
84 MODULE_PARM (nsp_burst_mode, "i");
85 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
87 /* Release IO ports after configuration? */
88 static int free_ports = 0;
89 MODULE_PARM (free_ports, "i");
90 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
92 /* /usr/src/linux/drivers/scsi/hosts.h */
93 static Scsi_Host_Template nsp_driver_template = {
94 .proc_name = "nsp_cs",
95 .proc_info = nsp_proc_info,
96 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
97 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
98 .detect = nsp_detect_old,
99 .release = nsp_release_old,
100 #endif
101 .info = nsp_info,
102 .queuecommand = nsp_queuecommand,
103 /* .eh_strategy_handler = nsp_eh_strategy,*/
104 /* .eh_abort_handler = nsp_eh_abort,*/
105 /* .eh_device_reset_handler = nsp_eh_device_reset,*/
106 .eh_bus_reset_handler = nsp_eh_bus_reset,
107 .eh_host_reset_handler = nsp_eh_host_reset,
108 .can_queue = 1,
109 .this_id = NSP_INITIATOR_ID,
110 .sg_tablesize = SG_ALL,
111 .cmd_per_lun = 1,
112 .use_clustering = DISABLE_CLUSTERING,
113 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
114 .use_new_eh_code = 1,
115 #endif
118 static dev_link_t *dev_list = NULL;
119 static dev_info_t dev_info = {"nsp_cs"};
121 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
126 * debug, error print
128 #ifndef NSP_DEBUG
129 # define NSP_DEBUG_MASK 0x000000
130 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
131 # define nsp_dbg(mask, args...) /* */
132 #else
133 # define NSP_DEBUG_MASK 0xffffff
134 # define nsp_msg(type, args...) \
135 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
136 # define nsp_dbg(mask, args...) \
137 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
138 #endif
140 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
141 #define NSP_DEBUG_REGISTER BIT(1)
142 #define NSP_DEBUG_AUTOSCSI BIT(2)
143 #define NSP_DEBUG_INTR BIT(3)
144 #define NSP_DEBUG_SGLIST BIT(4)
145 #define NSP_DEBUG_BUSFREE BIT(5)
146 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
147 #define NSP_DEBUG_RESELECTION BIT(7)
148 #define NSP_DEBUG_MSGINOCCUR BIT(8)
149 #define NSP_DEBUG_EEPROM BIT(9)
150 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
151 #define NSP_DEBUG_BUSRESET BIT(11)
152 #define NSP_DEBUG_RESTART BIT(12)
153 #define NSP_DEBUG_SYNC BIT(13)
154 #define NSP_DEBUG_WAIT BIT(14)
155 #define NSP_DEBUG_TARGETFLAG BIT(15)
156 #define NSP_DEBUG_PROC BIT(16)
157 #define NSP_DEBUG_INIT BIT(17)
158 #define NSP_DEBUG_DATA_IO BIT(18)
159 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
161 #define NSP_DEBUG_BUF_LEN 150
163 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
165 va_list args;
166 char buf[NSP_DEBUG_BUF_LEN];
168 va_start(args, fmt);
169 vsnprintf(buf, sizeof(buf), fmt, args);
170 va_end(args);
172 #ifndef NSP_DEBUG
173 printk("%snsp_cs: %s\n", type, buf);
174 #else
175 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
176 #endif
179 #ifdef NSP_DEBUG
180 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
182 va_list args;
183 char buf[NSP_DEBUG_BUF_LEN];
185 va_start(args, fmt);
186 vsnprintf(buf, sizeof(buf), fmt, args);
187 va_end(args);
189 if (mask & NSP_DEBUG_MASK) {
190 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
193 #endif
195 /***********************************************************/
197 /*====================================================
198 * Clenaup parameters and call done() functions.
199 * You must be set SCpnt->result before call this function.
201 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
203 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
205 data->CurrentSC = NULL;
207 SCpnt->scsi_done(SCpnt);
210 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
212 #ifdef NSP_DEBUG
213 /*unsigned int host_id = SCpnt->device->host->this_id;*/
214 /*unsigned int base = SCpnt->device->host->io_port;*/
215 unsigned char target = SCpnt->device->id;
216 #endif
217 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
219 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
220 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
221 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
223 SCpnt->scsi_done = done;
225 if (data->CurrentSC != NULL) {
226 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
227 SCpnt->result = DID_BAD_TARGET << 16;
228 nsp_scsi_done(SCpnt);
229 return SCSI_MLQUEUE_HOST_BUSY;
232 #if 0
233 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
234 This makes kernel crash when suspending... */
235 if (data->ScsiInfo->stop != 0) {
236 nsp_msg(KERN_INFO, "suspending device. reject command.");
237 SCpnt->result = DID_BAD_TARGET << 16;
238 nsp_scsi_done(SCpnt);
239 return SCSI_MLQUEUE_HOST_BUSY;
241 #endif
243 show_command(SCpnt);
245 data->CurrentSC = SCpnt;
247 SCpnt->SCp.Status = CHECK_CONDITION;
248 SCpnt->SCp.Message = 0;
249 SCpnt->SCp.have_data_in = IO_UNKNOWN;
250 SCpnt->SCp.sent_command = 0;
251 SCpnt->SCp.phase = PH_UNDETERMINED;
252 SCpnt->resid = SCpnt->request_bufflen;
254 /* setup scratch area
255 SCp.ptr : buffer pointer
256 SCp.this_residual : buffer length
257 SCp.buffer : next buffer
258 SCp.buffers_residual : left buffers in list
259 SCp.phase : current state of the command */
260 if (SCpnt->use_sg) {
261 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
262 SCpnt->SCp.ptr = BUFFER_ADDR;
263 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
264 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
265 } else {
266 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
267 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
268 SCpnt->SCp.buffer = NULL;
269 SCpnt->SCp.buffers_residual = 0;
272 if (nsphw_start_selection(SCpnt) == FALSE) {
273 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
274 SCpnt->result = DID_BUS_BUSY << 16;
275 nsp_scsi_done(SCpnt);
276 return SCSI_MLQUEUE_DEVICE_BUSY;
280 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
281 #ifdef NSP_DEBUG
282 data->CmdId++;
283 #endif
284 return 0;
288 * setup PIO FIFO transfer mode and enable/disable to data out
290 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
292 unsigned int base = data->BaseAddress;
293 unsigned char transfer_mode_reg;
295 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
297 if (enabled != FALSE) {
298 transfer_mode_reg = TRANSFER_GO | BRAIND;
299 } else {
300 transfer_mode_reg = 0;
303 transfer_mode_reg |= data->TransferMode;
305 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
308 static void nsphw_init_sync(nsp_hw_data *data)
310 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
311 .SyncPeriod = 0,
312 .SyncOffset = 0
314 int i;
316 /* setup sync data */
317 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
318 data->Sync[i] = tmp_sync;
323 * Initialize Ninja hardware
325 static int nsphw_init(nsp_hw_data *data)
327 unsigned int base = data->BaseAddress;
329 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
331 data->ScsiClockDiv = CLOCK_40M | FAST_20;
332 data->CurrentSC = NULL;
333 data->FifoCount = 0;
334 data->TransferMode = MODE_IO8;
336 nsphw_init_sync(data);
338 /* block all interrupts */
339 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
341 /* setup SCSI interface */
342 nsp_write(base, IFSELECT, IF_IFSEL);
344 nsp_index_write(base, SCSIIRQMODE, 0);
346 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
347 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
349 nsp_index_write(base, PARITYCTRL, 0);
350 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
351 ACK_COUNTER_CLEAR |
352 REQ_COUNTER_CLEAR |
353 HOST_COUNTER_CLEAR);
355 /* setup fifo asic */
356 nsp_write(base, IFSELECT, IF_REGSEL);
357 nsp_index_write(base, TERMPWRCTRL, 0);
358 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
359 nsp_msg(KERN_INFO, "terminator power on");
360 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
363 nsp_index_write(base, TIMERCOUNT, 0);
364 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
366 nsp_index_write(base, SYNCREG, 0);
367 nsp_index_write(base, ACKWIDTH, 0);
369 /* enable interrupts and ack them */
370 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
371 RESELECT_EI |
372 SCSI_RESET_IRQ_EI );
373 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
375 nsp_setup_fifo(data, FALSE);
377 return TRUE;
381 * Start selection phase
383 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
385 unsigned int host_id = SCpnt->device->host->this_id;
386 unsigned int base = SCpnt->device->host->io_port;
387 unsigned char target = SCpnt->device->id;
388 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
389 int time_out;
390 unsigned char phase, arbit;
392 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
394 phase = nsp_index_read(base, SCSIBUSMON);
395 if(phase != BUSMON_BUS_FREE) {
396 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
397 return FALSE;
400 /* start arbitration */
401 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
402 SCpnt->SCp.phase = PH_ARBSTART;
403 nsp_index_write(base, SETARBIT, ARBIT_GO);
405 time_out = 1000;
406 do {
407 /* XXX: what a stupid chip! */
408 arbit = nsp_index_read(base, ARBITSTATUS);
409 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
410 udelay(1); /* hold 1.2us */
411 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
412 (time_out-- != 0));
414 if (!(arbit & ARBIT_WIN)) {
415 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
416 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
417 return FALSE;
420 /* assert select line */
421 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
422 SCpnt->SCp.phase = PH_SELSTART;
423 udelay(3); /* wait 2.4us */
424 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
425 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
426 udelay(2); /* wait >1.2us */
427 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
428 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
429 /*udelay(1);*/ /* wait >90ns */
430 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
432 /* check selection timeout */
433 nsp_start_timer(SCpnt, 1000/51);
434 data->SelectionTimeOut = 1;
436 return TRUE;
439 struct nsp_sync_table {
440 unsigned int min_period;
441 unsigned int max_period;
442 unsigned int chip_period;
443 unsigned int ack_width;
446 static struct nsp_sync_table nsp_sync_table_40M[] = {
447 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
448 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
449 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
450 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
451 { 0, 0, 0, 0},
454 static struct nsp_sync_table nsp_sync_table_20M[] = {
455 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
456 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
457 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
458 { 0, 0, 0, 0},
462 * setup synchronous data transfer mode
464 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
466 unsigned char target = SCpnt->device->id;
467 // unsigned char lun = SCpnt->device->lun;
468 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
469 sync_data *sync = &(data->Sync[target]);
470 struct nsp_sync_table *sync_table;
471 unsigned int period, offset;
472 int i;
475 nsp_dbg(NSP_DEBUG_SYNC, "in");
477 period = sync->SyncPeriod;
478 offset = sync->SyncOffset;
480 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
482 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
483 sync_table = nsp_sync_table_20M;
484 } else {
485 sync_table = nsp_sync_table_40M;
488 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
489 if ( period >= sync_table->min_period &&
490 period <= sync_table->max_period ) {
491 break;
495 if (period != 0 && sync_table->max_period == 0) {
497 * No proper period/offset found
499 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
501 sync->SyncPeriod = 0;
502 sync->SyncOffset = 0;
503 sync->SyncRegister = 0;
504 sync->AckWidth = 0;
506 return FALSE;
509 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
510 (offset & SYNCREG_OFFSET_MASK);
511 sync->AckWidth = sync_table->ack_width;
513 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
515 return TRUE;
520 * start ninja hardware timer
522 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
524 unsigned int base = SCpnt->device->host->io_port;
525 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
527 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
528 data->TimerCount = time;
529 nsp_index_write(base, TIMERCOUNT, time);
533 * wait for bus phase change
535 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
537 unsigned int base = SCpnt->device->host->io_port;
538 unsigned char reg;
539 int time_out;
541 //nsp_dbg(NSP_DEBUG_INTR, "in");
543 time_out = 100;
545 do {
546 reg = nsp_index_read(base, SCSIBUSMON);
547 if (reg == 0xff) {
548 break;
550 } while ((time_out-- != 0) && (reg & mask) != 0);
552 if (time_out == 0) {
553 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
556 return 0;
560 * expect Ninja Irq
562 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
563 unsigned char current_phase,
564 unsigned char mask)
566 unsigned int base = SCpnt->device->host->io_port;
567 int time_out;
568 unsigned char phase, i_src;
570 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
572 time_out = 100;
573 do {
574 phase = nsp_index_read(base, SCSIBUSMON);
575 if (phase == 0xff) {
576 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
577 return -1;
579 i_src = nsp_read(base, IRQSTATUS);
580 if (i_src & IRQSTATUS_SCSI) {
581 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
582 return 0;
584 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
585 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
586 return 1;
588 } while(time_out-- != 0);
590 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
591 return -1;
595 * transfer SCSI message
597 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
599 unsigned int base = SCpnt->device->host->io_port;
600 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
601 char *buf = data->MsgBuffer;
602 int len = min(MSGBUF_SIZE, data->MsgLen);
603 int ptr;
604 int ret;
606 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
607 for (ptr = 0; len > 0; len--, ptr++) {
609 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
610 if (ret <= 0) {
611 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
612 return 0;
615 /* if last byte, negate ATN */
616 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
617 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
620 /* read & write message */
621 if (phase & BUSMON_IO) {
622 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
623 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
624 } else {
625 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
626 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
628 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
631 return len;
635 * get extra SCSI data from fifo
637 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
639 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
640 unsigned int count;
642 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
644 if (SCpnt->SCp.have_data_in != IO_IN) {
645 return 0;
648 count = nsp_fifo_count(SCpnt);
649 if (data->FifoCount == count) {
650 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
651 return 0;
655 * XXX: NSP_QUIRK
656 * data phase skip only occures in case of SCSI_LOW_READ
658 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
659 SCpnt->SCp.phase = PH_DATA;
660 nsp_pio_read(SCpnt);
661 nsp_setup_fifo(data, FALSE);
663 return 0;
667 * accept reselection
669 static int nsp_reselected(Scsi_Cmnd *SCpnt)
671 unsigned int base = SCpnt->device->host->io_port;
672 unsigned int host_id = SCpnt->device->host->this_id;
673 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
674 unsigned char bus_reg;
675 unsigned char id_reg, tmp;
676 int target;
678 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
680 id_reg = nsp_index_read(base, RESELECTID);
681 tmp = id_reg & (~BIT(host_id));
682 target = 0;
683 while(tmp != 0) {
684 if (tmp & BIT(0)) {
685 break;
687 tmp >>= 1;
688 target++;
691 if (SCpnt->device->id != target) {
692 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
695 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
697 nsp_nexus(SCpnt);
698 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
699 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
700 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
702 return TRUE;
706 * count how many data transferd
708 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
710 unsigned int base = SCpnt->device->host->io_port;
711 unsigned int count;
712 unsigned int l, m, h, dummy;
714 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
716 l = nsp_index_read(base, TRANSFERCOUNT);
717 m = nsp_index_read(base, TRANSFERCOUNT);
718 h = nsp_index_read(base, TRANSFERCOUNT);
719 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
721 count = (h << 16) | (m << 8) | (l << 0);
723 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
725 return count;
728 /* fifo size */
729 #define RFIFO_CRIT 64
730 #define WFIFO_CRIT 64
733 * read data in DATA IN phase
735 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
737 unsigned int base = SCpnt->device->host->io_port;
738 unsigned long mmio_base = SCpnt->device->host->base;
739 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
740 long time_out;
741 int ocount, res;
742 unsigned char stat, fifo_stat;
744 ocount = data->FifoCount;
746 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",
747 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
749 time_out = 1000;
751 while ((time_out-- != 0) &&
752 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
754 stat = nsp_index_read(base, SCSIBUSMON);
755 stat &= BUSMON_PHASE_MASK;
758 res = nsp_fifo_count(SCpnt) - ocount;
759 //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);
760 if (res == 0) { /* if some data avilable ? */
761 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
762 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
763 continue;
764 } else {
765 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
766 break;
770 fifo_stat = nsp_read(base, FIFOSTATUS);
771 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
772 stat == BUSPHASE_DATA_IN) {
773 continue;
776 res = min(res, SCpnt->SCp.this_residual);
778 switch (data->TransferMode) {
779 case MODE_IO32:
780 res &= ~(BIT(1)|BIT(0)); /* align 4 */
781 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
782 break;
783 case MODE_IO8:
784 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
785 break;
787 case MODE_MEM32:
788 res &= ~(BIT(1)|BIT(0)); /* align 4 */
789 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
790 break;
792 default:
793 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
794 return;
797 SCpnt->resid -= res;
798 SCpnt->SCp.ptr += res;
799 SCpnt->SCp.this_residual -= res;
800 ocount += res;
801 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
803 /* go to next scatter list if available */
804 if (SCpnt->SCp.this_residual == 0 &&
805 SCpnt->SCp.buffers_residual != 0 ) {
806 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
807 SCpnt->SCp.buffers_residual--;
808 SCpnt->SCp.buffer++;
809 SCpnt->SCp.ptr = BUFFER_ADDR;
810 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
811 time_out = 1000;
813 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
817 data->FifoCount = ocount;
819 if (time_out == 0) {
820 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
821 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
823 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
824 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
828 * write data in DATA OUT phase
830 static void nsp_pio_write(Scsi_Cmnd *SCpnt)
832 unsigned int base = SCpnt->device->host->io_port;
833 unsigned long mmio_base = SCpnt->device->host->base;
834 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
835 int time_out;
836 int ocount, res;
837 unsigned char stat;
839 ocount = data->FifoCount;
841 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
842 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
844 time_out = 1000;
846 while ((time_out-- != 0) &&
847 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
848 stat = nsp_index_read(base, SCSIBUSMON);
849 stat &= BUSMON_PHASE_MASK;
851 if (stat != BUSPHASE_DATA_OUT) {
852 res = ocount - nsp_fifo_count(SCpnt);
854 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
855 /* Put back pointer */
856 SCpnt->resid += res;
857 SCpnt->SCp.ptr -= res;
858 SCpnt->SCp.this_residual += res;
859 ocount -= res;
861 break;
864 res = ocount - nsp_fifo_count(SCpnt);
865 if (res > 0) { /* write all data? */
866 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
867 continue;
870 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
872 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
873 switch (data->TransferMode) {
874 case MODE_IO32:
875 res &= ~(BIT(1)|BIT(0)); /* align 4 */
876 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
877 break;
878 case MODE_IO8:
879 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
880 break;
882 case MODE_MEM32:
883 res &= ~(BIT(1)|BIT(0)); /* align 4 */
884 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
885 break;
887 default:
888 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
889 break;
892 SCpnt->resid -= res;
893 SCpnt->SCp.ptr += res;
894 SCpnt->SCp.this_residual -= res;
895 ocount += res;
897 /* go to next scatter list if available */
898 if (SCpnt->SCp.this_residual == 0 &&
899 SCpnt->SCp.buffers_residual != 0 ) {
900 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
901 SCpnt->SCp.buffers_residual--;
902 SCpnt->SCp.buffer++;
903 SCpnt->SCp.ptr = BUFFER_ADDR;
904 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
905 time_out = 1000;
909 data->FifoCount = ocount;
911 if (time_out == 0) {
912 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
914 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
915 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
917 #undef RFIFO_CRIT
918 #undef WFIFO_CRIT
921 * setup synchronous/asynchronous data transfer mode
923 static int nsp_nexus(Scsi_Cmnd *SCpnt)
925 unsigned int base = SCpnt->device->host->io_port;
926 unsigned char target = SCpnt->device->id;
927 // unsigned char lun = SCpnt->device->lun;
928 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
929 sync_data *sync = &(data->Sync[target]);
931 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
933 /* setup synch transfer registers */
934 nsp_index_write(base, SYNCREG, sync->SyncRegister);
935 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
937 if (SCpnt->use_sg == 0 ||
938 SCpnt->resid % 4 != 0 ||
939 SCpnt->resid <= PAGE_SIZE ) {
940 data->TransferMode = MODE_IO8;
941 } else if (nsp_burst_mode == BURST_MEM32) {
942 data->TransferMode = MODE_MEM32;
943 } else if (nsp_burst_mode == BURST_IO32) {
944 data->TransferMode = MODE_IO32;
945 } else {
946 data->TransferMode = MODE_IO8;
949 /* setup pdma fifo */
950 nsp_setup_fifo(data, TRUE);
952 /* clear ack counter */
953 data->FifoCount = 0;
954 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
955 ACK_COUNTER_CLEAR |
956 REQ_COUNTER_CLEAR |
957 HOST_COUNTER_CLEAR);
959 return 0;
962 #include "nsp_message.c"
964 * interrupt handler
966 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
968 unsigned int base;
969 unsigned char irq_status, irq_phase, phase;
970 Scsi_Cmnd *tmpSC;
971 unsigned char target, lun;
972 unsigned int *sync_neg;
973 int i, tmp;
974 nsp_hw_data *data;
977 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
978 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
980 if ( dev_id != NULL &&
981 ((scsi_info_t *)dev_id)->host != NULL ) {
982 scsi_info_t *info = (scsi_info_t *)dev_id;
984 data = (nsp_hw_data *)info->host->hostdata;
985 } else {
986 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
987 return IRQ_NONE;
990 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
992 base = data->BaseAddress;
993 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
996 * interrupt check
998 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
999 irq_status = nsp_read(base, IRQSTATUS);
1000 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
1001 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
1002 nsp_write(base, IRQCONTROL, 0);
1003 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
1004 return IRQ_NONE;
1007 /* XXX: IMPORTANT
1008 * Do not read an irq_phase register if no scsi phase interrupt.
1009 * Unless, you should lose a scsi phase interrupt.
1011 phase = nsp_index_read(base, SCSIBUSMON);
1012 if((irq_status & IRQSTATUS_SCSI) != 0) {
1013 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1014 } else {
1015 irq_phase = 0;
1018 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1021 * timer interrupt handler (scsi vs timer interrupts)
1023 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1024 if (data->TimerCount != 0) {
1025 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1026 nsp_index_write(base, TIMERCOUNT, 0);
1027 nsp_index_write(base, TIMERCOUNT, 0);
1028 data->TimerCount = 0;
1031 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1032 data->SelectionTimeOut == 0) {
1033 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1034 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1035 return IRQ_HANDLED;
1038 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1040 if ((irq_status & IRQSTATUS_SCSI) &&
1041 (irq_phase & SCSI_RESET_IRQ)) {
1042 nsp_msg(KERN_ERR, "bus reset (power off?)");
1044 nsphw_init(data);
1045 nsp_bus_reset(data);
1047 if(data->CurrentSC != NULL) {
1048 tmpSC = data->CurrentSC;
1049 tmpSC->result = (DID_RESET << 16) |
1050 ((tmpSC->SCp.Message & 0xff) << 8) |
1051 ((tmpSC->SCp.Status & 0xff) << 0);
1052 nsp_scsi_done(tmpSC);
1054 return IRQ_HANDLED;
1057 if (data->CurrentSC == NULL) {
1058 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);
1059 nsphw_init(data);
1060 nsp_bus_reset(data);
1061 return IRQ_HANDLED;
1064 tmpSC = data->CurrentSC;
1065 target = tmpSC->device->id;
1066 lun = tmpSC->device->lun;
1067 sync_neg = &(data->Sync[target].SyncNegotiation);
1070 * parse hardware SCSI irq reasons register
1072 if (irq_status & IRQSTATUS_SCSI) {
1073 if (irq_phase & RESELECT_IRQ) {
1074 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1075 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1076 if (nsp_reselected(tmpSC) != FALSE) {
1077 return IRQ_HANDLED;
1081 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1082 return IRQ_HANDLED;
1086 //show_phase(tmpSC);
1088 switch(tmpSC->SCp.phase) {
1089 case PH_SELSTART:
1090 // *sync_neg = SYNC_NOT_YET;
1091 if ((phase & BUSMON_BSY) == 0) {
1092 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1093 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1094 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1095 data->SelectionTimeOut = 0;
1096 nsp_index_write(base, SCSIBUSCTRL, 0);
1098 tmpSC->result = DID_TIME_OUT << 16;
1099 nsp_scsi_done(tmpSC);
1101 return IRQ_HANDLED;
1103 data->SelectionTimeOut += 1;
1104 nsp_start_timer(tmpSC, 1000/51);
1105 return IRQ_HANDLED;
1108 /* attention assert */
1109 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1110 data->SelectionTimeOut = 0;
1111 tmpSC->SCp.phase = PH_SELECTED;
1112 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1113 udelay(1);
1114 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1115 return IRQ_HANDLED;
1117 break;
1119 case PH_RESELECT:
1120 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1121 // *sync_neg = SYNC_NOT_YET;
1122 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1124 tmpSC->result = DID_ABORT << 16;
1125 nsp_scsi_done(tmpSC);
1126 return IRQ_HANDLED;
1128 /* fall thru */
1129 default:
1130 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1131 return IRQ_HANDLED;
1133 break;
1137 * SCSI sequencer
1139 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1141 /* normal disconnect */
1142 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1143 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1144 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1146 //*sync_neg = SYNC_NOT_YET;
1148 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1149 tmpSC->result = (DID_OK << 16) |
1150 ((tmpSC->SCp.Message & 0xff) << 8) |
1151 ((tmpSC->SCp.Status & 0xff) << 0);
1152 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1153 nsp_scsi_done(tmpSC);
1155 return IRQ_HANDLED;
1158 return IRQ_HANDLED;
1162 /* check unexpected bus free state */
1163 if (phase == 0) {
1164 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1166 *sync_neg = SYNC_NG;
1167 tmpSC->result = DID_ERROR << 16;
1168 nsp_scsi_done(tmpSC);
1169 return IRQ_HANDLED;
1172 switch (phase & BUSMON_PHASE_MASK) {
1173 case BUSPHASE_COMMAND:
1174 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1175 if ((phase & BUSMON_REQ) == 0) {
1176 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1177 return IRQ_HANDLED;
1180 tmpSC->SCp.phase = PH_COMMAND;
1182 nsp_nexus(tmpSC);
1184 /* write scsi command */
1185 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1186 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1187 for (i = 0; i < tmpSC->cmd_len; i++) {
1188 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1190 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1191 break;
1193 case BUSPHASE_DATA_OUT:
1194 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1196 tmpSC->SCp.phase = PH_DATA;
1197 tmpSC->SCp.have_data_in = IO_OUT;
1199 nsp_pio_write(tmpSC);
1201 break;
1203 case BUSPHASE_DATA_IN:
1204 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1206 tmpSC->SCp.phase = PH_DATA;
1207 tmpSC->SCp.have_data_in = IO_IN;
1209 nsp_pio_read(tmpSC);
1211 break;
1213 case BUSPHASE_STATUS:
1214 nsp_dataphase_bypass(tmpSC);
1215 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1217 tmpSC->SCp.phase = PH_STATUS;
1219 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1220 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1222 break;
1224 case BUSPHASE_MESSAGE_OUT:
1225 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1226 if ((phase & BUSMON_REQ) == 0) {
1227 goto timer_out;
1230 tmpSC->SCp.phase = PH_MSG_OUT;
1232 //*sync_neg = SYNC_NOT_YET;
1234 data->MsgLen = i = 0;
1235 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1237 if (*sync_neg == SYNC_NOT_YET) {
1238 data->Sync[target].SyncPeriod = 0;
1239 data->Sync[target].SyncOffset = 0;
1241 /**/
1242 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1243 data->MsgBuffer[i] = 3; i++;
1244 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1245 data->MsgBuffer[i] = 0x0c; i++;
1246 data->MsgBuffer[i] = 15; i++;
1247 /**/
1249 data->MsgLen = i;
1251 nsp_analyze_sdtr(tmpSC);
1252 show_message(data);
1253 nsp_message_out(tmpSC);
1254 break;
1256 case BUSPHASE_MESSAGE_IN:
1257 nsp_dataphase_bypass(tmpSC);
1258 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1259 if ((phase & BUSMON_REQ) == 0) {
1260 goto timer_out;
1263 tmpSC->SCp.phase = PH_MSG_IN;
1264 nsp_message_in(tmpSC);
1266 /**/
1267 if (*sync_neg == SYNC_NOT_YET) {
1268 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1270 if (data->MsgLen >= 5 &&
1271 data->MsgBuffer[0] == MSG_EXTENDED &&
1272 data->MsgBuffer[1] == 3 &&
1273 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1274 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1275 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1276 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1277 *sync_neg = SYNC_OK;
1278 } else {
1279 data->Sync[target].SyncPeriod = 0;
1280 data->Sync[target].SyncOffset = 0;
1281 *sync_neg = SYNC_NG;
1283 nsp_analyze_sdtr(tmpSC);
1285 /**/
1287 /* search last messeage byte */
1288 tmp = -1;
1289 for (i = 0; i < data->MsgLen; i++) {
1290 tmp = data->MsgBuffer[i];
1291 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1292 i += (1 + data->MsgBuffer[i+1]);
1295 tmpSC->SCp.Message = tmp;
1297 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1298 show_message(data);
1300 break;
1302 case BUSPHASE_SELECT:
1303 default:
1304 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1306 break;
1309 //nsp_dbg(NSP_DEBUG_INTR, "out");
1310 return IRQ_HANDLED;
1312 timer_out:
1313 nsp_start_timer(tmpSC, 1000/102);
1314 return IRQ_HANDLED;
1317 #ifdef NSP_DEBUG
1318 #include "nsp_debug.c"
1319 #endif /* NSP_DEBUG */
1321 /*----------------------------------------------------------------*/
1322 /* look for ninja3 card and init if found */
1323 /*----------------------------------------------------------------*/
1324 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
1326 struct Scsi_Host *host; /* registered host structure */
1327 nsp_hw_data *data_b = &nsp_data_base, *data;
1329 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1330 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1331 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1332 #else
1333 host = scsi_register(sht, sizeof(nsp_hw_data));
1334 #endif
1335 if (host == NULL) {
1336 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1337 return NULL;
1340 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1341 data = (nsp_hw_data *)host->hostdata;
1342 data->ScsiInfo->host = host;
1343 #ifdef NSP_DEBUG
1344 data->CmdId = 0;
1345 #endif
1347 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1349 host->unique_id = data->BaseAddress;
1350 host->io_port = data->BaseAddress;
1351 host->n_io_port = data->NumAddress;
1352 host->irq = data->IrqNumber;
1353 host->base = data->MmioAddress;
1355 spin_lock_init(&(data->Lock));
1357 snprintf(data->nspinfo,
1358 sizeof(data->nspinfo),
1359 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1360 host->io_port, host->io_port + host->n_io_port - 1,
1361 host->base,
1362 host->irq);
1363 sht->name = data->nspinfo;
1365 nsp_dbg(NSP_DEBUG_INIT, "end");
1368 return host; /* detect done. */
1371 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1372 static int nsp_detect_old(Scsi_Host_Template *sht)
1374 if (nsp_detect(sht) == NULL) {
1375 return 0;
1376 } else {
1377 //MOD_INC_USE_COUNT;
1378 return 1;
1383 static int nsp_release_old(struct Scsi_Host *shpnt)
1385 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1387 /* PCMCIA Card Service dose same things below. */
1388 /* So we do nothing. */
1389 //if (shpnt->irq) {
1390 // free_irq(shpnt->irq, data->ScsiInfo);
1392 //if (shpnt->io_port) {
1393 // release_region(shpnt->io_port, shpnt->n_io_port);
1396 //MOD_DEC_USE_COUNT;
1398 return 0;
1400 #endif
1402 /*----------------------------------------------------------------*/
1403 /* return info string */
1404 /*----------------------------------------------------------------*/
1405 static const char *nsp_info(struct Scsi_Host *shpnt)
1407 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1409 return data->nspinfo;
1412 #undef SPRINTF
1413 #define SPRINTF(args...) \
1414 do { \
1415 if(length > (pos - buffer)) { \
1416 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1417 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1419 } while(0)
1420 static int
1421 nsp_proc_info(
1422 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1423 struct Scsi_Host *host,
1424 #endif
1425 char *buffer,
1426 char **start,
1427 off_t offset,
1428 int length,
1429 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1430 int hostno,
1431 #endif
1432 int inout)
1434 int id;
1435 char *pos = buffer;
1436 int thislength;
1437 int speed;
1438 unsigned long flags;
1439 nsp_hw_data *data;
1440 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1441 struct Scsi_Host *host;
1442 #else
1443 int hostno;
1444 #endif
1445 if (inout) {
1446 return -EINVAL;
1449 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1450 hostno = host->host_no;
1451 #else
1452 /* search this HBA host */
1453 host = scsi_host_hn_get(hostno);
1454 if (host == NULL) {
1455 return -ESRCH;
1457 #endif
1458 data = (nsp_hw_data *)host->hostdata;
1461 SPRINTF("NinjaSCSI status\n\n");
1462 SPRINTF("Driver version: $Revision: 1.23 $\n");
1463 SPRINTF("SCSI host No.: %d\n", hostno);
1464 SPRINTF("IRQ: %d\n", host->irq);
1465 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1466 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1467 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1469 SPRINTF("burst transfer mode: ");
1470 switch (nsp_burst_mode) {
1471 case BURST_IO8:
1472 SPRINTF("io8");
1473 break;
1474 case BURST_IO32:
1475 SPRINTF("io32");
1476 break;
1477 case BURST_MEM32:
1478 SPRINTF("mem32");
1479 break;
1480 default:
1481 SPRINTF("???");
1482 break;
1484 SPRINTF("\n");
1487 spin_lock_irqsave(&(data->Lock), flags);
1488 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1489 spin_unlock_irqrestore(&(data->Lock), flags);
1491 SPRINTF("SDTR status\n");
1492 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1494 SPRINTF("id %d: ", id);
1496 if (id == host->this_id) {
1497 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1498 continue;
1501 switch(data->Sync[id].SyncNegotiation) {
1502 case SYNC_OK:
1503 SPRINTF(" sync");
1504 break;
1505 case SYNC_NG:
1506 SPRINTF("async");
1507 break;
1508 case SYNC_NOT_YET:
1509 SPRINTF(" none");
1510 break;
1511 default:
1512 SPRINTF("?????");
1513 break;
1516 if (data->Sync[id].SyncPeriod != 0) {
1517 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1519 SPRINTF(" transfer %d.%dMB/s, offset %d",
1520 speed / 1000,
1521 speed % 1000,
1522 data->Sync[id].SyncOffset
1525 SPRINTF("\n");
1528 thislength = pos - (buffer + offset);
1530 if(thislength < 0) {
1531 *start = NULL;
1532 return 0;
1536 thislength = min(thislength, length);
1537 *start = buffer + offset;
1539 return thislength;
1541 #undef SPRINTF
1543 /*---------------------------------------------------------------*/
1544 /* error handler */
1545 /*---------------------------------------------------------------*/
1547 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
1549 return FAILED;
1553 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1555 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1557 return nsp_eh_bus_reset(SCpnt);
1561 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
1563 nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
1565 return FAILED;
1568 static int nsp_bus_reset(nsp_hw_data *data)
1570 unsigned int base = data->BaseAddress;
1571 int i;
1573 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1575 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1576 mdelay(100); /* 100ms */
1577 nsp_index_write(base, SCSIBUSCTRL, 0);
1578 for(i = 0; i < 5; i++) {
1579 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1582 nsphw_init_sync(data);
1584 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1586 return SUCCESS;
1589 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1591 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1593 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1595 return nsp_bus_reset(data);
1598 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1600 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1602 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1604 nsphw_init(data);
1606 return SUCCESS;
1610 /**********************************************************************
1611 PCMCIA functions
1612 **********************************************************************/
1614 /*======================================================================
1615 nsp_cs_attach() creates an "instance" of the driver, allocating
1616 local data structures for one device. The device is registered
1617 with Card Services.
1619 The dev_link structure is initialized, but we don't actually
1620 configure the card at this point -- we wait until we receive a
1621 card insertion event.
1622 ======================================================================*/
1623 static dev_link_t *nsp_cs_attach(void)
1625 scsi_info_t *info;
1626 client_reg_t client_reg;
1627 dev_link_t *link;
1628 int ret, i;
1629 nsp_hw_data *data = &nsp_data_base;
1631 nsp_dbg(NSP_DEBUG_INIT, "in");
1633 /* Create new SCSI device */
1634 info = kmalloc(sizeof(*info), GFP_KERNEL);
1635 if (info == NULL) { return NULL; }
1636 memset(info, 0, sizeof(*info));
1637 link = &info->link;
1638 link->priv = info;
1639 data->ScsiInfo = info;
1641 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1643 /* The io structure describes IO port mapping */
1644 link->io.NumPorts1 = 0x10;
1645 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1646 link->io.IOAddrLines = 10; /* not used */
1648 /* Interrupt setup */
1649 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1650 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
1651 if (irq_list[0] == -1) {
1652 link->irq.IRQInfo2 = irq_mask;
1653 } else {
1654 for (i = 0; i < 4; i++) {
1655 link->irq.IRQInfo2 |= BIT(irq_list[i]);
1659 /* Interrupt handler */
1660 link->irq.Handler = &nspintr;
1661 link->irq.Instance = info;
1662 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1664 /* General socket configuration */
1665 link->conf.Attributes = CONF_ENABLE_IRQ;
1666 link->conf.Vcc = 50;
1667 link->conf.IntType = INT_MEMORY_AND_IO;
1668 link->conf.Present = PRESENT_OPTION;
1671 /* Register with Card Services */
1672 link->next = dev_list;
1673 dev_list = link;
1674 client_reg.dev_info = &dev_info;
1675 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
1676 client_reg.EventMask =
1677 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1678 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1679 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1680 client_reg.event_handler = &nsp_cs_event;
1681 client_reg.Version = 0x0210;
1682 client_reg.event_callback_args.client_data = link;
1683 ret = pcmcia_register_client(&link->handle, &client_reg);
1684 if (ret != CS_SUCCESS) {
1685 cs_error(link->handle, RegisterClient, ret);
1686 nsp_cs_detach(link);
1687 return NULL;
1691 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1692 return link;
1693 } /* nsp_cs_attach */
1696 /*======================================================================
1697 This deletes a driver "instance". The device is de-registered
1698 with Card Services. If it has been released, all local data
1699 structures are freed. Otherwise, the structures will be freed
1700 when the device is released.
1701 ======================================================================*/
1702 static void nsp_cs_detach(dev_link_t *link)
1704 dev_link_t **linkp;
1706 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1708 /* Locate device structure */
1709 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1710 if (*linkp == link) {
1711 break;
1714 if (*linkp == NULL) {
1715 return;
1718 if (link->state & DEV_CONFIG)
1719 nsp_cs_release(link);
1721 /* Break the link with Card Services */
1722 if (link->handle) {
1723 pcmcia_deregister_client(link->handle);
1726 /* Unlink device structure, free bits */
1727 *linkp = link->next;
1728 kfree(link->priv);
1729 link->priv = NULL;
1731 } /* nsp_cs_detach */
1734 /*======================================================================
1735 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1736 is received, to configure the PCMCIA socket, and to make the
1737 ethernet device available to the system.
1738 ======================================================================*/
1739 #define CS_CHECK(fn, ret) \
1740 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1741 /*====================================================================*/
1742 static void nsp_cs_config(dev_link_t *link)
1744 client_handle_t handle = link->handle;
1745 scsi_info_t *info = link->priv;
1746 tuple_t tuple;
1747 cisparse_t parse;
1748 int last_ret, last_fn;
1749 unsigned char tuple_data[64];
1750 config_info_t conf;
1751 win_req_t req;
1752 memreq_t map;
1753 cistpl_cftable_entry_t dflt = { 0 };
1754 struct Scsi_Host *host;
1755 nsp_hw_data *data = &nsp_data_base;
1756 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1757 Scsi_Device *dev;
1758 dev_node_t **tail, *node;
1759 #endif
1761 nsp_dbg(NSP_DEBUG_INIT, "in");
1763 tuple.DesiredTuple = CISTPL_CONFIG;
1764 tuple.Attributes = 0;
1765 tuple.TupleData = tuple_data;
1766 tuple.TupleDataMax = sizeof(tuple_data);
1767 tuple.TupleOffset = 0;
1768 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1769 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1770 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1771 link->conf.ConfigBase = parse.config.base;
1772 link->conf.Present = parse.config.rmask[0];
1774 /* Configure card */
1775 link->state |= DEV_CONFIG;
1777 /* Look up the current Vcc */
1778 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1779 link->conf.Vcc = conf.Vcc;
1781 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1782 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1783 while (1) {
1784 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1786 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1787 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1788 goto next_entry;
1790 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1791 if (cfg->index == 0) { goto next_entry; }
1792 link->conf.ConfigIndex = cfg->index;
1794 /* Does this card need audio output? */
1795 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1796 link->conf.Attributes |= CONF_ENABLE_SPKR;
1797 link->conf.Status = CCSR_AUDIO_ENA;
1800 /* Use power settings for Vcc and Vpp if present */
1801 /* Note that the CIS values need to be rescaled */
1802 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1803 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1804 goto next_entry;
1806 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1807 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1808 goto next_entry;
1812 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1813 link->conf.Vpp1 = link->conf.Vpp2 =
1814 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1815 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1816 link->conf.Vpp1 = link->conf.Vpp2 =
1817 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1820 /* Do we need to allocate an interrupt? */
1821 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1822 link->conf.Attributes |= CONF_ENABLE_IRQ;
1825 /* IO window settings */
1826 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1827 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1828 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1829 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1830 if (!(io->flags & CISTPL_IO_8BIT))
1831 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1832 if (!(io->flags & CISTPL_IO_16BIT))
1833 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1834 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1835 link->io.BasePort1 = io->win[0].base;
1836 link->io.NumPorts1 = io->win[0].len;
1837 if (io->nwin > 1) {
1838 link->io.Attributes2 = link->io.Attributes1;
1839 link->io.BasePort2 = io->win[1].base;
1840 link->io.NumPorts2 = io->win[1].len;
1842 /* This reserves IO space but doesn't actually enable it */
1843 if (pcmcia_request_io(link->handle, &link->io) != 0)
1844 goto next_entry;
1847 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1848 cistpl_mem_t *mem =
1849 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1850 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1851 req.Attributes |= WIN_ENABLE;
1852 req.Base = mem->win[0].host_addr;
1853 req.Size = mem->win[0].len;
1854 if (req.Size < 0x1000) {
1855 req.Size = 0x1000;
1857 req.AccessSpeed = 0;
1858 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1859 goto next_entry;
1860 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1861 if (pcmcia_map_mem_page(link->win, &map) != 0)
1862 goto next_entry;
1864 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1865 data->MmioLength = req.Size;
1867 /* If we got this far, we're cool! */
1868 break;
1870 next_entry:
1871 nsp_dbg(NSP_DEBUG_INIT, "next");
1873 if (link->io.NumPorts1) {
1874 pcmcia_release_io(link->handle, &link->io);
1876 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1879 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1880 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1882 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1884 if (free_ports) {
1885 if (link->io.BasePort1) {
1886 release_region(link->io.BasePort1, link->io.NumPorts1);
1888 if (link->io.BasePort2) {
1889 release_region(link->io.BasePort2, link->io.NumPorts2);
1893 /* Set port and IRQ */
1894 data->BaseAddress = link->io.BasePort1;
1895 data->NumAddress = link->io.NumPorts1;
1896 data->IrqNumber = link->irq.AssignedIRQ;
1898 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1899 data->BaseAddress, data->NumAddress, data->IrqNumber);
1901 if(nsphw_init(data) == FALSE) {
1902 goto cs_failed;
1905 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1906 host = nsp_detect(&nsp_driver_template);
1907 #else
1908 scsi_register_host(&nsp_driver_template);
1909 for (host = scsi_host_get_next(NULL); host != NULL;
1910 host = scsi_host_get_next(host)) {
1911 if (host->hostt == &nsp_driver_template) {
1912 break;
1915 #endif
1917 if (host == NULL) {
1918 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1919 goto cs_failed;
1923 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1924 scsi_add_host (host, NULL);
1925 scsi_scan_host(host);
1927 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1928 link->dev = &info->node;
1929 info->host = host;
1931 #else
1932 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1933 tail = &link->dev;
1934 info->ndev = 0;
1936 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1938 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1939 unsigned long id;
1940 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1941 ((dev->channel & 0x0f) << 8) +
1942 ((dev->host->host_no & 0x0f) << 12);
1943 node = &info->node[info->ndev];
1944 node->minor = 0;
1945 switch (dev->type) {
1946 case TYPE_TAPE:
1947 node->major = SCSI_TAPE_MAJOR;
1948 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1949 break;
1950 case TYPE_DISK:
1951 case TYPE_MOD:
1952 node->major = SCSI_DISK0_MAJOR;
1953 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1954 break;
1955 case TYPE_ROM:
1956 case TYPE_WORM:
1957 node->major = SCSI_CDROM_MAJOR;
1958 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1959 break;
1960 default:
1961 node->major = SCSI_GENERIC_MAJOR;
1962 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1963 break;
1965 *tail = node; tail = &node->next;
1966 info->ndev++;
1967 info->host = dev->host;
1970 *tail = NULL;
1971 if (info->ndev == 0) {
1972 nsp_msg(KERN_INFO, "no SCSI devices found");
1974 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1975 #endif
1977 /* Finally, report what we've done */
1978 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1979 link->conf.ConfigIndex,
1980 link->conf.Vcc/10, link->conf.Vcc%10);
1981 if (link->conf.Vpp1) {
1982 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1984 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1985 printk(", irq %d", link->irq.AssignedIRQ);
1987 if (link->io.NumPorts1) {
1988 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1989 link->io.BasePort1+link->io.NumPorts1-1);
1991 if (link->io.NumPorts2)
1992 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1993 link->io.BasePort2+link->io.NumPorts2-1);
1994 if (link->win)
1995 printk(", mem 0x%06lx-0x%06lx", req.Base,
1996 req.Base+req.Size-1);
1997 printk("\n");
1999 link->state &= ~DEV_CONFIG_PENDING;
2000 return;
2002 cs_failed:
2003 nsp_dbg(NSP_DEBUG_INIT, "config fail");
2004 cs_error(link->handle, last_fn, last_ret);
2005 nsp_cs_release(link);
2007 return;
2008 } /* nsp_cs_config */
2009 #undef CS_CHECK
2012 /*======================================================================
2013 After a card is removed, nsp_cs_release() will unregister the net
2014 device, and release the PCMCIA configuration. If the device is
2015 still open, this will be postponed until it is closed.
2016 ======================================================================*/
2017 static void nsp_cs_release(dev_link_t *link)
2019 scsi_info_t *info = link->priv;
2020 nsp_hw_data *data = NULL;
2022 if (info->host == NULL) {
2023 nsp_msg(KERN_DEBUG, "unexpected card release call.");
2024 } else {
2025 data = (nsp_hw_data *)info->host->hostdata;
2028 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
2030 /* Unlink the device chain */
2031 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2032 if (info->host != NULL) {
2033 scsi_remove_host(info->host);
2035 #else
2036 scsi_unregister_host(&nsp_driver_template);
2037 #endif
2038 link->dev = NULL;
2040 if (link->win) {
2041 if (data != NULL) {
2042 iounmap((void *)(data->MmioAddress));
2044 pcmcia_release_window(link->win);
2046 pcmcia_release_configuration(link->handle);
2047 if (link->io.NumPorts1) {
2048 pcmcia_release_io(link->handle, &link->io);
2050 if (link->irq.AssignedIRQ) {
2051 pcmcia_release_irq(link->handle, &link->irq);
2053 link->state &= ~DEV_CONFIG;
2054 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2055 if (info->host != NULL) {
2056 scsi_host_put(info->host);
2058 #endif
2059 } /* nsp_cs_release */
2061 /*======================================================================
2063 The card status event handler. Mostly, this schedules other
2064 stuff to run after an event is received. A CARD_REMOVAL event
2065 also sets some flags to discourage the net drivers from trying
2066 to talk to the card any more.
2068 When a CARD_REMOVAL event is received, we immediately set a flag
2069 to block future accesses to this device. All the functions that
2070 actually access the device should check this flag to make sure
2071 the card is still present.
2073 ======================================================================*/
2074 static int nsp_cs_event(event_t event,
2075 int priority,
2076 event_callback_args_t *args)
2078 dev_link_t *link = args->client_data;
2079 scsi_info_t *info = link->priv;
2080 nsp_hw_data *data;
2082 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2084 switch (event) {
2085 case CS_EVENT_CARD_REMOVAL:
2086 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2087 link->state &= ~DEV_PRESENT;
2088 if (link->state & DEV_CONFIG) {
2089 ((scsi_info_t *)link->priv)->stop = 1;
2090 nsp_cs_release(link);
2092 break;
2094 case CS_EVENT_CARD_INSERTION:
2095 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2096 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2097 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2098 info->bus = args->bus;
2099 #endif
2100 nsp_cs_config(link);
2101 break;
2103 case CS_EVENT_PM_SUSPEND:
2104 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2105 link->state |= DEV_SUSPEND;
2106 /* Fall through... */
2107 case CS_EVENT_RESET_PHYSICAL:
2108 /* Mark the device as stopped, to block IO until later */
2109 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2111 if (info->host != NULL) {
2112 nsp_msg(KERN_INFO, "clear SDTR status");
2114 data = (nsp_hw_data *)info->host->hostdata;
2116 nsphw_init_sync(data);
2119 info->stop = 1;
2120 if (link->state & DEV_CONFIG) {
2121 pcmcia_release_configuration(link->handle);
2123 break;
2125 case CS_EVENT_PM_RESUME:
2126 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2127 link->state &= ~DEV_SUSPEND;
2128 /* Fall through... */
2129 case CS_EVENT_CARD_RESET:
2130 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2131 if (link->state & DEV_CONFIG) {
2132 pcmcia_request_configuration(link->handle, &link->conf);
2134 info->stop = 0;
2136 if (info->host != NULL) {
2137 nsp_msg(KERN_INFO, "reset host and bus");
2139 data = (nsp_hw_data *)info->host->hostdata;
2141 nsphw_init (data);
2142 nsp_bus_reset(data);
2145 break;
2147 default:
2148 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2149 break;
2151 nsp_dbg(NSP_DEBUG_INIT, "end");
2152 return 0;
2153 } /* nsp_cs_event */
2155 /*======================================================================*
2156 * module entry point
2157 *====================================================================*/
2158 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2159 static struct pcmcia_driver nsp_driver = {
2160 .owner = THIS_MODULE,
2161 .drv = {
2162 .name = "nsp_cs",
2164 .attach = nsp_cs_attach,
2165 .detach = nsp_cs_detach,
2167 #endif
2169 static int __init nsp_cs_init(void)
2171 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2172 nsp_msg(KERN_INFO, "loading...");
2174 return pcmcia_register_driver(&nsp_driver);
2175 #else
2176 servinfo_t serv;
2178 nsp_msg(KERN_INFO, "loading...");
2179 pcmcia_get_card_services_info(&serv);
2180 if (serv.Revision != CS_RELEASE_CODE) {
2181 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2182 return -EINVAL;
2184 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2186 nsp_dbg(NSP_DEBUG_INIT, "out");
2187 return 0;
2188 #endif
2191 static void __exit nsp_cs_exit(void)
2193 nsp_msg(KERN_INFO, "unloading...");
2195 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2196 pcmcia_unregister_driver(&nsp_driver);
2197 #else
2198 unregister_pcmcia_driver(&dev_info);
2199 #endif
2201 /* XXX: this really needs to move into generic code.. */
2202 while (dev_list != NULL) {
2203 if (dev_list->state & DEV_CONFIG) {
2204 nsp_cs_release(dev_list);
2206 nsp_cs_detach(dev_list);
2211 module_init(nsp_cs_init)
2212 module_exit(nsp_cs_exit)
2214 /* end */