x86/xen: resume timer irqs early
[linux/fpc-iii.git] / drivers / scsi / pcmcia / nsp_cs.c
blob987fbb1b244e9661be7401d6de906f444840a1ea
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 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/ioport.h>
35 #include <linux/delay.h>
36 #include <linux/interrupt.h>
37 #include <linux/major.h>
38 #include <linux/blkdev.h>
39 #include <linux/stat.h>
41 #include <asm/io.h>
42 #include <asm/irq.h>
44 #include <../drivers/scsi/scsi.h>
45 #include <scsi/scsi_host.h>
47 #include <scsi/scsi.h>
48 #include <scsi/scsi_ioctl.h>
50 #include <pcmcia/cistpl.h>
51 #include <pcmcia/cisreg.h>
52 #include <pcmcia/ds.h>
54 #include "nsp_cs.h"
56 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
57 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
58 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
59 #ifdef MODULE_LICENSE
60 MODULE_LICENSE("GPL");
61 #endif
63 #include "nsp_io.h"
65 /*====================================================================*/
66 /* Parameters that can be set with 'insmod' */
68 static int nsp_burst_mode = BURST_MEM32;
69 module_param(nsp_burst_mode, int, 0);
70 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
72 /* Release IO ports after configuration? */
73 static bool free_ports = 0;
74 module_param(free_ports, bool, 0);
75 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
77 static struct scsi_host_template nsp_driver_template = {
78 .proc_name = "nsp_cs",
79 .show_info = nsp_show_info,
80 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
81 .info = nsp_info,
82 .queuecommand = nsp_queuecommand,
83 /* .eh_abort_handler = nsp_eh_abort,*/
84 .eh_bus_reset_handler = nsp_eh_bus_reset,
85 .eh_host_reset_handler = nsp_eh_host_reset,
86 .can_queue = 1,
87 .this_id = NSP_INITIATOR_ID,
88 .sg_tablesize = SG_ALL,
89 .cmd_per_lun = 1,
90 .use_clustering = DISABLE_CLUSTERING,
93 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
98 * debug, error print
100 #ifndef NSP_DEBUG
101 # define NSP_DEBUG_MASK 0x000000
102 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
103 # define nsp_dbg(mask, args...) /* */
104 #else
105 # define NSP_DEBUG_MASK 0xffffff
106 # define nsp_msg(type, args...) \
107 nsp_cs_message (__func__, __LINE__, (type), args)
108 # define nsp_dbg(mask, args...) \
109 nsp_cs_dmessage(__func__, __LINE__, (mask), args)
110 #endif
112 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
113 #define NSP_DEBUG_REGISTER BIT(1)
114 #define NSP_DEBUG_AUTOSCSI BIT(2)
115 #define NSP_DEBUG_INTR BIT(3)
116 #define NSP_DEBUG_SGLIST BIT(4)
117 #define NSP_DEBUG_BUSFREE BIT(5)
118 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
119 #define NSP_DEBUG_RESELECTION BIT(7)
120 #define NSP_DEBUG_MSGINOCCUR BIT(8)
121 #define NSP_DEBUG_EEPROM BIT(9)
122 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
123 #define NSP_DEBUG_BUSRESET BIT(11)
124 #define NSP_DEBUG_RESTART BIT(12)
125 #define NSP_DEBUG_SYNC BIT(13)
126 #define NSP_DEBUG_WAIT BIT(14)
127 #define NSP_DEBUG_TARGETFLAG BIT(15)
128 #define NSP_DEBUG_PROC BIT(16)
129 #define NSP_DEBUG_INIT BIT(17)
130 #define NSP_DEBUG_DATA_IO BIT(18)
131 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
133 #define NSP_DEBUG_BUF_LEN 150
135 static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
137 scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
140 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
142 va_list args;
143 char buf[NSP_DEBUG_BUF_LEN];
145 va_start(args, fmt);
146 vsnprintf(buf, sizeof(buf), fmt, args);
147 va_end(args);
149 #ifndef NSP_DEBUG
150 printk("%snsp_cs: %s\n", type, buf);
151 #else
152 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
153 #endif
156 #ifdef NSP_DEBUG
157 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
159 va_list args;
160 char buf[NSP_DEBUG_BUF_LEN];
162 va_start(args, fmt);
163 vsnprintf(buf, sizeof(buf), fmt, args);
164 va_end(args);
166 if (mask & NSP_DEBUG_MASK) {
167 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
170 #endif
172 /***********************************************************/
174 /*====================================================
175 * Clenaup parameters and call done() functions.
176 * You must be set SCpnt->result before call this function.
178 static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
180 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
182 data->CurrentSC = NULL;
184 SCpnt->scsi_done(SCpnt);
187 static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
188 void (*done)(struct scsi_cmnd *))
190 #ifdef NSP_DEBUG
191 /*unsigned int host_id = SCpnt->device->host->this_id;*/
192 /*unsigned int base = SCpnt->device->host->io_port;*/
193 unsigned char target = scmd_id(SCpnt);
194 #endif
195 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
197 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
198 "SCpnt=0x%p target=%d lun=%d sglist=0x%p bufflen=%d sg_count=%d",
199 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
200 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
201 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
203 SCpnt->scsi_done = done;
205 if (data->CurrentSC != NULL) {
206 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
207 SCpnt->result = DID_BAD_TARGET << 16;
208 nsp_scsi_done(SCpnt);
209 return 0;
212 #if 0
213 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
214 This makes kernel crash when suspending... */
215 if (data->ScsiInfo->stop != 0) {
216 nsp_msg(KERN_INFO, "suspending device. reject command.");
217 SCpnt->result = DID_BAD_TARGET << 16;
218 nsp_scsi_done(SCpnt);
219 return SCSI_MLQUEUE_HOST_BUSY;
221 #endif
223 show_command(SCpnt);
225 data->CurrentSC = SCpnt;
227 SCpnt->SCp.Status = CHECK_CONDITION;
228 SCpnt->SCp.Message = 0;
229 SCpnt->SCp.have_data_in = IO_UNKNOWN;
230 SCpnt->SCp.sent_command = 0;
231 SCpnt->SCp.phase = PH_UNDETERMINED;
232 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
234 /* setup scratch area
235 SCp.ptr : buffer pointer
236 SCp.this_residual : buffer length
237 SCp.buffer : next buffer
238 SCp.buffers_residual : left buffers in list
239 SCp.phase : current state of the command */
240 if (scsi_bufflen(SCpnt)) {
241 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
242 SCpnt->SCp.ptr = BUFFER_ADDR;
243 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
244 SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
245 } else {
246 SCpnt->SCp.ptr = NULL;
247 SCpnt->SCp.this_residual = 0;
248 SCpnt->SCp.buffer = NULL;
249 SCpnt->SCp.buffers_residual = 0;
252 if (nsphw_start_selection(SCpnt) == FALSE) {
253 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
254 SCpnt->result = DID_BUS_BUSY << 16;
255 nsp_scsi_done(SCpnt);
256 return 0;
260 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
261 #ifdef NSP_DEBUG
262 data->CmdId++;
263 #endif
264 return 0;
267 static DEF_SCSI_QCMD(nsp_queuecommand)
270 * setup PIO FIFO transfer mode and enable/disable to data out
272 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
274 unsigned int base = data->BaseAddress;
275 unsigned char transfer_mode_reg;
277 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
279 if (enabled != FALSE) {
280 transfer_mode_reg = TRANSFER_GO | BRAIND;
281 } else {
282 transfer_mode_reg = 0;
285 transfer_mode_reg |= data->TransferMode;
287 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
290 static void nsphw_init_sync(nsp_hw_data *data)
292 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
293 .SyncPeriod = 0,
294 .SyncOffset = 0
296 int i;
298 /* setup sync data */
299 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
300 data->Sync[i] = tmp_sync;
305 * Initialize Ninja hardware
307 static int nsphw_init(nsp_hw_data *data)
309 unsigned int base = data->BaseAddress;
311 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
313 data->ScsiClockDiv = CLOCK_40M | FAST_20;
314 data->CurrentSC = NULL;
315 data->FifoCount = 0;
316 data->TransferMode = MODE_IO8;
318 nsphw_init_sync(data);
320 /* block all interrupts */
321 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
323 /* setup SCSI interface */
324 nsp_write(base, IFSELECT, IF_IFSEL);
326 nsp_index_write(base, SCSIIRQMODE, 0);
328 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
329 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
331 nsp_index_write(base, PARITYCTRL, 0);
332 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
333 ACK_COUNTER_CLEAR |
334 REQ_COUNTER_CLEAR |
335 HOST_COUNTER_CLEAR);
337 /* setup fifo asic */
338 nsp_write(base, IFSELECT, IF_REGSEL);
339 nsp_index_write(base, TERMPWRCTRL, 0);
340 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
341 nsp_msg(KERN_INFO, "terminator power on");
342 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
345 nsp_index_write(base, TIMERCOUNT, 0);
346 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
348 nsp_index_write(base, SYNCREG, 0);
349 nsp_index_write(base, ACKWIDTH, 0);
351 /* enable interrupts and ack them */
352 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
353 RESELECT_EI |
354 SCSI_RESET_IRQ_EI );
355 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
357 nsp_setup_fifo(data, FALSE);
359 return TRUE;
363 * Start selection phase
365 static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
367 unsigned int host_id = SCpnt->device->host->this_id;
368 unsigned int base = SCpnt->device->host->io_port;
369 unsigned char target = scmd_id(SCpnt);
370 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
371 int time_out;
372 unsigned char phase, arbit;
374 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
376 phase = nsp_index_read(base, SCSIBUSMON);
377 if(phase != BUSMON_BUS_FREE) {
378 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
379 return FALSE;
382 /* start arbitration */
383 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
384 SCpnt->SCp.phase = PH_ARBSTART;
385 nsp_index_write(base, SETARBIT, ARBIT_GO);
387 time_out = 1000;
388 do {
389 /* XXX: what a stupid chip! */
390 arbit = nsp_index_read(base, ARBITSTATUS);
391 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
392 udelay(1); /* hold 1.2us */
393 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
394 (time_out-- != 0));
396 if (!(arbit & ARBIT_WIN)) {
397 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
398 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
399 return FALSE;
402 /* assert select line */
403 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
404 SCpnt->SCp.phase = PH_SELSTART;
405 udelay(3); /* wait 2.4us */
406 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
407 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
408 udelay(2); /* wait >1.2us */
409 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
410 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
411 /*udelay(1);*/ /* wait >90ns */
412 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
414 /* check selection timeout */
415 nsp_start_timer(SCpnt, 1000/51);
416 data->SelectionTimeOut = 1;
418 return TRUE;
421 struct nsp_sync_table {
422 unsigned int min_period;
423 unsigned int max_period;
424 unsigned int chip_period;
425 unsigned int ack_width;
428 static struct nsp_sync_table nsp_sync_table_40M[] = {
429 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
430 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
431 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
432 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
433 { 0, 0, 0, 0},
436 static struct nsp_sync_table nsp_sync_table_20M[] = {
437 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
438 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
439 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
440 { 0, 0, 0, 0},
444 * setup synchronous data transfer mode
446 static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
448 unsigned char target = scmd_id(SCpnt);
449 // unsigned char lun = SCpnt->device->lun;
450 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
451 sync_data *sync = &(data->Sync[target]);
452 struct nsp_sync_table *sync_table;
453 unsigned int period, offset;
454 int i;
457 nsp_dbg(NSP_DEBUG_SYNC, "in");
459 period = sync->SyncPeriod;
460 offset = sync->SyncOffset;
462 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
464 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
465 sync_table = nsp_sync_table_20M;
466 } else {
467 sync_table = nsp_sync_table_40M;
470 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
471 if ( period >= sync_table->min_period &&
472 period <= sync_table->max_period ) {
473 break;
477 if (period != 0 && sync_table->max_period == 0) {
479 * No proper period/offset found
481 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
483 sync->SyncPeriod = 0;
484 sync->SyncOffset = 0;
485 sync->SyncRegister = 0;
486 sync->AckWidth = 0;
488 return FALSE;
491 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
492 (offset & SYNCREG_OFFSET_MASK);
493 sync->AckWidth = sync_table->ack_width;
495 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
497 return TRUE;
502 * start ninja hardware timer
504 static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
506 unsigned int base = SCpnt->device->host->io_port;
507 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
509 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
510 data->TimerCount = time;
511 nsp_index_write(base, TIMERCOUNT, time);
515 * wait for bus phase change
517 static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
518 char *str)
520 unsigned int base = SCpnt->device->host->io_port;
521 unsigned char reg;
522 int time_out;
524 //nsp_dbg(NSP_DEBUG_INTR, "in");
526 time_out = 100;
528 do {
529 reg = nsp_index_read(base, SCSIBUSMON);
530 if (reg == 0xff) {
531 break;
533 } while ((--time_out != 0) && (reg & mask) != 0);
535 if (time_out == 0) {
536 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
539 return 0;
543 * expect Ninja Irq
545 static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
546 unsigned char current_phase,
547 unsigned char mask)
549 unsigned int base = SCpnt->device->host->io_port;
550 int time_out;
551 unsigned char phase, i_src;
553 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
555 time_out = 100;
556 do {
557 phase = nsp_index_read(base, SCSIBUSMON);
558 if (phase == 0xff) {
559 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
560 return -1;
562 i_src = nsp_read(base, IRQSTATUS);
563 if (i_src & IRQSTATUS_SCSI) {
564 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
565 return 0;
567 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
568 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
569 return 1;
571 } while(time_out-- != 0);
573 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
574 return -1;
578 * transfer SCSI message
580 static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
582 unsigned int base = SCpnt->device->host->io_port;
583 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
584 char *buf = data->MsgBuffer;
585 int len = min(MSGBUF_SIZE, data->MsgLen);
586 int ptr;
587 int ret;
589 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
590 for (ptr = 0; len > 0; len--, ptr++) {
592 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
593 if (ret <= 0) {
594 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
595 return 0;
598 /* if last byte, negate ATN */
599 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
600 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
603 /* read & write message */
604 if (phase & BUSMON_IO) {
605 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
606 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
607 } else {
608 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
609 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
611 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
614 return len;
618 * get extra SCSI data from fifo
620 static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
622 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
623 unsigned int count;
625 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
627 if (SCpnt->SCp.have_data_in != IO_IN) {
628 return 0;
631 count = nsp_fifo_count(SCpnt);
632 if (data->FifoCount == count) {
633 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
634 return 0;
638 * XXX: NSP_QUIRK
639 * data phase skip only occures in case of SCSI_LOW_READ
641 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
642 SCpnt->SCp.phase = PH_DATA;
643 nsp_pio_read(SCpnt);
644 nsp_setup_fifo(data, FALSE);
646 return 0;
650 * accept reselection
652 static int nsp_reselected(struct scsi_cmnd *SCpnt)
654 unsigned int base = SCpnt->device->host->io_port;
655 unsigned int host_id = SCpnt->device->host->this_id;
656 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
657 unsigned char bus_reg;
658 unsigned char id_reg, tmp;
659 int target;
661 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
663 id_reg = nsp_index_read(base, RESELECTID);
664 tmp = id_reg & (~BIT(host_id));
665 target = 0;
666 while(tmp != 0) {
667 if (tmp & BIT(0)) {
668 break;
670 tmp >>= 1;
671 target++;
674 if (scmd_id(SCpnt) != target) {
675 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
678 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
680 nsp_nexus(SCpnt);
681 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
682 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
683 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
685 return TRUE;
689 * count how many data transferd
691 static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
693 unsigned int base = SCpnt->device->host->io_port;
694 unsigned int count;
695 unsigned int l, m, h, dummy;
697 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
699 l = nsp_index_read(base, TRANSFERCOUNT);
700 m = nsp_index_read(base, TRANSFERCOUNT);
701 h = nsp_index_read(base, TRANSFERCOUNT);
702 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
704 count = (h << 16) | (m << 8) | (l << 0);
706 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
708 return count;
711 /* fifo size */
712 #define RFIFO_CRIT 64
713 #define WFIFO_CRIT 64
716 * read data in DATA IN phase
718 static void nsp_pio_read(struct scsi_cmnd *SCpnt)
720 unsigned int base = SCpnt->device->host->io_port;
721 unsigned long mmio_base = SCpnt->device->host->base;
722 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
723 long time_out;
724 int ocount, res;
725 unsigned char stat, fifo_stat;
727 ocount = data->FifoCount;
729 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",
730 SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
731 SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
732 SCpnt->SCp.buffers_residual);
734 time_out = 1000;
736 while ((time_out-- != 0) &&
737 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
739 stat = nsp_index_read(base, SCSIBUSMON);
740 stat &= BUSMON_PHASE_MASK;
743 res = nsp_fifo_count(SCpnt) - ocount;
744 //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);
745 if (res == 0) { /* if some data available ? */
746 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
747 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
748 continue;
749 } else {
750 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
751 break;
755 fifo_stat = nsp_read(base, FIFOSTATUS);
756 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
757 stat == BUSPHASE_DATA_IN) {
758 continue;
761 res = min(res, SCpnt->SCp.this_residual);
763 switch (data->TransferMode) {
764 case MODE_IO32:
765 res &= ~(BIT(1)|BIT(0)); /* align 4 */
766 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
767 break;
768 case MODE_IO8:
769 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
770 break;
772 case MODE_MEM32:
773 res &= ~(BIT(1)|BIT(0)); /* align 4 */
774 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
775 break;
777 default:
778 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
779 return;
782 nsp_inc_resid(SCpnt, -res);
783 SCpnt->SCp.ptr += res;
784 SCpnt->SCp.this_residual -= res;
785 ocount += res;
786 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
788 /* go to next scatter list if available */
789 if (SCpnt->SCp.this_residual == 0 &&
790 SCpnt->SCp.buffers_residual != 0 ) {
791 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
792 SCpnt->SCp.buffers_residual--;
793 SCpnt->SCp.buffer++;
794 SCpnt->SCp.ptr = BUFFER_ADDR;
795 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
796 time_out = 1000;
798 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
802 data->FifoCount = ocount;
804 if (time_out < 0) {
805 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
806 scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
807 SCpnt->SCp.buffers_residual);
809 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
810 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
811 scsi_get_resid(SCpnt));
815 * write data in DATA OUT phase
817 static void nsp_pio_write(struct scsi_cmnd *SCpnt)
819 unsigned int base = SCpnt->device->host->io_port;
820 unsigned long mmio_base = SCpnt->device->host->base;
821 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
822 int time_out;
823 int ocount, res;
824 unsigned char stat;
826 ocount = data->FifoCount;
828 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
829 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual,
830 SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
831 scsi_get_resid(SCpnt));
833 time_out = 1000;
835 while ((time_out-- != 0) &&
836 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
837 stat = nsp_index_read(base, SCSIBUSMON);
838 stat &= BUSMON_PHASE_MASK;
840 if (stat != BUSPHASE_DATA_OUT) {
841 res = ocount - nsp_fifo_count(SCpnt);
843 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
844 /* Put back pointer */
845 nsp_inc_resid(SCpnt, res);
846 SCpnt->SCp.ptr -= res;
847 SCpnt->SCp.this_residual += res;
848 ocount -= res;
850 break;
853 res = ocount - nsp_fifo_count(SCpnt);
854 if (res > 0) { /* write all data? */
855 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
856 continue;
859 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
861 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
862 switch (data->TransferMode) {
863 case MODE_IO32:
864 res &= ~(BIT(1)|BIT(0)); /* align 4 */
865 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
866 break;
867 case MODE_IO8:
868 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
869 break;
871 case MODE_MEM32:
872 res &= ~(BIT(1)|BIT(0)); /* align 4 */
873 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
874 break;
876 default:
877 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
878 break;
881 nsp_inc_resid(SCpnt, -res);
882 SCpnt->SCp.ptr += res;
883 SCpnt->SCp.this_residual -= res;
884 ocount += res;
886 /* go to next scatter list if available */
887 if (SCpnt->SCp.this_residual == 0 &&
888 SCpnt->SCp.buffers_residual != 0 ) {
889 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
890 SCpnt->SCp.buffers_residual--;
891 SCpnt->SCp.buffer++;
892 SCpnt->SCp.ptr = BUFFER_ADDR;
893 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
894 time_out = 1000;
898 data->FifoCount = ocount;
900 if (time_out < 0) {
901 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
902 scsi_get_resid(SCpnt));
904 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
905 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
906 scsi_get_resid(SCpnt));
908 #undef RFIFO_CRIT
909 #undef WFIFO_CRIT
912 * setup synchronous/asynchronous data transfer mode
914 static int nsp_nexus(struct scsi_cmnd *SCpnt)
916 unsigned int base = SCpnt->device->host->io_port;
917 unsigned char target = scmd_id(SCpnt);
918 // unsigned char lun = SCpnt->device->lun;
919 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
920 sync_data *sync = &(data->Sync[target]);
922 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
924 /* setup synch transfer registers */
925 nsp_index_write(base, SYNCREG, sync->SyncRegister);
926 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
928 if (scsi_get_resid(SCpnt) % 4 != 0 ||
929 scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
930 data->TransferMode = MODE_IO8;
931 } else if (nsp_burst_mode == BURST_MEM32) {
932 data->TransferMode = MODE_MEM32;
933 } else if (nsp_burst_mode == BURST_IO32) {
934 data->TransferMode = MODE_IO32;
935 } else {
936 data->TransferMode = MODE_IO8;
939 /* setup pdma fifo */
940 nsp_setup_fifo(data, TRUE);
942 /* clear ack counter */
943 data->FifoCount = 0;
944 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
945 ACK_COUNTER_CLEAR |
946 REQ_COUNTER_CLEAR |
947 HOST_COUNTER_CLEAR);
949 return 0;
952 #include "nsp_message.c"
954 * interrupt handler
956 static irqreturn_t nspintr(int irq, void *dev_id)
958 unsigned int base;
959 unsigned char irq_status, irq_phase, phase;
960 struct scsi_cmnd *tmpSC;
961 unsigned char target, lun;
962 unsigned int *sync_neg;
963 int i, tmp;
964 nsp_hw_data *data;
967 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
968 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
970 if ( dev_id != NULL &&
971 ((scsi_info_t *)dev_id)->host != NULL ) {
972 scsi_info_t *info = (scsi_info_t *)dev_id;
974 data = (nsp_hw_data *)info->host->hostdata;
975 } else {
976 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
977 return IRQ_NONE;
980 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
982 base = data->BaseAddress;
983 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
986 * interrupt check
988 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
989 irq_status = nsp_read(base, IRQSTATUS);
990 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
991 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
992 nsp_write(base, IRQCONTROL, 0);
993 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
994 return IRQ_NONE;
997 /* XXX: IMPORTANT
998 * Do not read an irq_phase register if no scsi phase interrupt.
999 * Unless, you should lose a scsi phase interrupt.
1001 phase = nsp_index_read(base, SCSIBUSMON);
1002 if((irq_status & IRQSTATUS_SCSI) != 0) {
1003 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1004 } else {
1005 irq_phase = 0;
1008 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1011 * timer interrupt handler (scsi vs timer interrupts)
1013 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1014 if (data->TimerCount != 0) {
1015 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1016 nsp_index_write(base, TIMERCOUNT, 0);
1017 nsp_index_write(base, TIMERCOUNT, 0);
1018 data->TimerCount = 0;
1021 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1022 data->SelectionTimeOut == 0) {
1023 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1024 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1025 return IRQ_HANDLED;
1028 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1030 if ((irq_status & IRQSTATUS_SCSI) &&
1031 (irq_phase & SCSI_RESET_IRQ)) {
1032 nsp_msg(KERN_ERR, "bus reset (power off?)");
1034 nsphw_init(data);
1035 nsp_bus_reset(data);
1037 if(data->CurrentSC != NULL) {
1038 tmpSC = data->CurrentSC;
1039 tmpSC->result = (DID_RESET << 16) |
1040 ((tmpSC->SCp.Message & 0xff) << 8) |
1041 ((tmpSC->SCp.Status & 0xff) << 0);
1042 nsp_scsi_done(tmpSC);
1044 return IRQ_HANDLED;
1047 if (data->CurrentSC == NULL) {
1048 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);
1049 nsphw_init(data);
1050 nsp_bus_reset(data);
1051 return IRQ_HANDLED;
1054 tmpSC = data->CurrentSC;
1055 target = tmpSC->device->id;
1056 lun = tmpSC->device->lun;
1057 sync_neg = &(data->Sync[target].SyncNegotiation);
1060 * parse hardware SCSI irq reasons register
1062 if (irq_status & IRQSTATUS_SCSI) {
1063 if (irq_phase & RESELECT_IRQ) {
1064 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1065 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1066 if (nsp_reselected(tmpSC) != FALSE) {
1067 return IRQ_HANDLED;
1071 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1072 return IRQ_HANDLED;
1076 //show_phase(tmpSC);
1078 switch(tmpSC->SCp.phase) {
1079 case PH_SELSTART:
1080 // *sync_neg = SYNC_NOT_YET;
1081 if ((phase & BUSMON_BSY) == 0) {
1082 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1083 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1084 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1085 data->SelectionTimeOut = 0;
1086 nsp_index_write(base, SCSIBUSCTRL, 0);
1088 tmpSC->result = DID_TIME_OUT << 16;
1089 nsp_scsi_done(tmpSC);
1091 return IRQ_HANDLED;
1093 data->SelectionTimeOut += 1;
1094 nsp_start_timer(tmpSC, 1000/51);
1095 return IRQ_HANDLED;
1098 /* attention assert */
1099 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1100 data->SelectionTimeOut = 0;
1101 tmpSC->SCp.phase = PH_SELECTED;
1102 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1103 udelay(1);
1104 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1105 return IRQ_HANDLED;
1107 break;
1109 case PH_RESELECT:
1110 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1111 // *sync_neg = SYNC_NOT_YET;
1112 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1114 tmpSC->result = DID_ABORT << 16;
1115 nsp_scsi_done(tmpSC);
1116 return IRQ_HANDLED;
1118 /* fall thru */
1119 default:
1120 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1121 return IRQ_HANDLED;
1123 break;
1127 * SCSI sequencer
1129 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1131 /* normal disconnect */
1132 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1133 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1134 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1136 //*sync_neg = SYNC_NOT_YET;
1138 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1139 tmpSC->result = (DID_OK << 16) |
1140 ((tmpSC->SCp.Message & 0xff) << 8) |
1141 ((tmpSC->SCp.Status & 0xff) << 0);
1142 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1143 nsp_scsi_done(tmpSC);
1145 return IRQ_HANDLED;
1148 return IRQ_HANDLED;
1152 /* check unexpected bus free state */
1153 if (phase == 0) {
1154 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1156 *sync_neg = SYNC_NG;
1157 tmpSC->result = DID_ERROR << 16;
1158 nsp_scsi_done(tmpSC);
1159 return IRQ_HANDLED;
1162 switch (phase & BUSMON_PHASE_MASK) {
1163 case BUSPHASE_COMMAND:
1164 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1165 if ((phase & BUSMON_REQ) == 0) {
1166 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1167 return IRQ_HANDLED;
1170 tmpSC->SCp.phase = PH_COMMAND;
1172 nsp_nexus(tmpSC);
1174 /* write scsi command */
1175 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1176 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1177 for (i = 0; i < tmpSC->cmd_len; i++) {
1178 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1180 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1181 break;
1183 case BUSPHASE_DATA_OUT:
1184 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1186 tmpSC->SCp.phase = PH_DATA;
1187 tmpSC->SCp.have_data_in = IO_OUT;
1189 nsp_pio_write(tmpSC);
1191 break;
1193 case BUSPHASE_DATA_IN:
1194 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1196 tmpSC->SCp.phase = PH_DATA;
1197 tmpSC->SCp.have_data_in = IO_IN;
1199 nsp_pio_read(tmpSC);
1201 break;
1203 case BUSPHASE_STATUS:
1204 nsp_dataphase_bypass(tmpSC);
1205 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1207 tmpSC->SCp.phase = PH_STATUS;
1209 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1210 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1212 break;
1214 case BUSPHASE_MESSAGE_OUT:
1215 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1216 if ((phase & BUSMON_REQ) == 0) {
1217 goto timer_out;
1220 tmpSC->SCp.phase = PH_MSG_OUT;
1222 //*sync_neg = SYNC_NOT_YET;
1224 data->MsgLen = i = 0;
1225 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1227 if (*sync_neg == SYNC_NOT_YET) {
1228 data->Sync[target].SyncPeriod = 0;
1229 data->Sync[target].SyncOffset = 0;
1231 /**/
1232 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1233 data->MsgBuffer[i] = 3; i++;
1234 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1235 data->MsgBuffer[i] = 0x0c; i++;
1236 data->MsgBuffer[i] = 15; i++;
1237 /**/
1239 data->MsgLen = i;
1241 nsp_analyze_sdtr(tmpSC);
1242 show_message(data);
1243 nsp_message_out(tmpSC);
1244 break;
1246 case BUSPHASE_MESSAGE_IN:
1247 nsp_dataphase_bypass(tmpSC);
1248 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1249 if ((phase & BUSMON_REQ) == 0) {
1250 goto timer_out;
1253 tmpSC->SCp.phase = PH_MSG_IN;
1254 nsp_message_in(tmpSC);
1256 /**/
1257 if (*sync_neg == SYNC_NOT_YET) {
1258 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1260 if (data->MsgLen >= 5 &&
1261 data->MsgBuffer[0] == MSG_EXTENDED &&
1262 data->MsgBuffer[1] == 3 &&
1263 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1264 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1265 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1266 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1267 *sync_neg = SYNC_OK;
1268 } else {
1269 data->Sync[target].SyncPeriod = 0;
1270 data->Sync[target].SyncOffset = 0;
1271 *sync_neg = SYNC_NG;
1273 nsp_analyze_sdtr(tmpSC);
1275 /**/
1277 /* search last messeage byte */
1278 tmp = -1;
1279 for (i = 0; i < data->MsgLen; i++) {
1280 tmp = data->MsgBuffer[i];
1281 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1282 i += (1 + data->MsgBuffer[i+1]);
1285 tmpSC->SCp.Message = tmp;
1287 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1288 show_message(data);
1290 break;
1292 case BUSPHASE_SELECT:
1293 default:
1294 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1296 break;
1299 //nsp_dbg(NSP_DEBUG_INTR, "out");
1300 return IRQ_HANDLED;
1302 timer_out:
1303 nsp_start_timer(tmpSC, 1000/102);
1304 return IRQ_HANDLED;
1307 #ifdef NSP_DEBUG
1308 #include "nsp_debug.c"
1309 #endif /* NSP_DEBUG */
1311 /*----------------------------------------------------------------*/
1312 /* look for ninja3 card and init if found */
1313 /*----------------------------------------------------------------*/
1314 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1316 struct Scsi_Host *host; /* registered host structure */
1317 nsp_hw_data *data_b = &nsp_data_base, *data;
1319 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1320 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1321 if (host == NULL) {
1322 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1323 return NULL;
1326 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1327 data = (nsp_hw_data *)host->hostdata;
1328 data->ScsiInfo->host = host;
1329 #ifdef NSP_DEBUG
1330 data->CmdId = 0;
1331 #endif
1333 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1335 host->unique_id = data->BaseAddress;
1336 host->io_port = data->BaseAddress;
1337 host->n_io_port = data->NumAddress;
1338 host->irq = data->IrqNumber;
1339 host->base = data->MmioAddress;
1341 spin_lock_init(&(data->Lock));
1343 snprintf(data->nspinfo,
1344 sizeof(data->nspinfo),
1345 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1346 host->io_port, host->io_port + host->n_io_port - 1,
1347 host->base,
1348 host->irq);
1349 sht->name = data->nspinfo;
1351 nsp_dbg(NSP_DEBUG_INIT, "end");
1354 return host; /* detect done. */
1357 /*----------------------------------------------------------------*/
1358 /* return info string */
1359 /*----------------------------------------------------------------*/
1360 static const char *nsp_info(struct Scsi_Host *shpnt)
1362 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1364 return data->nspinfo;
1367 #undef SPRINTF
1368 #define SPRINTF(args...) seq_printf(m, ##args)
1370 static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1372 int id;
1373 int speed;
1374 unsigned long flags;
1375 nsp_hw_data *data;
1376 int hostno;
1378 hostno = host->host_no;
1379 data = (nsp_hw_data *)host->hostdata;
1381 SPRINTF("NinjaSCSI status\n\n");
1382 SPRINTF("Driver version: $Revision: 1.23 $\n");
1383 SPRINTF("SCSI host No.: %d\n", hostno);
1384 SPRINTF("IRQ: %d\n", host->irq);
1385 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1386 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1387 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1389 SPRINTF("burst transfer mode: ");
1390 switch (nsp_burst_mode) {
1391 case BURST_IO8:
1392 SPRINTF("io8");
1393 break;
1394 case BURST_IO32:
1395 SPRINTF("io32");
1396 break;
1397 case BURST_MEM32:
1398 SPRINTF("mem32");
1399 break;
1400 default:
1401 SPRINTF("???");
1402 break;
1404 SPRINTF("\n");
1407 spin_lock_irqsave(&(data->Lock), flags);
1408 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1409 spin_unlock_irqrestore(&(data->Lock), flags);
1411 SPRINTF("SDTR status\n");
1412 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1414 SPRINTF("id %d: ", id);
1416 if (id == host->this_id) {
1417 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1418 continue;
1421 switch(data->Sync[id].SyncNegotiation) {
1422 case SYNC_OK:
1423 SPRINTF(" sync");
1424 break;
1425 case SYNC_NG:
1426 SPRINTF("async");
1427 break;
1428 case SYNC_NOT_YET:
1429 SPRINTF(" none");
1430 break;
1431 default:
1432 SPRINTF("?????");
1433 break;
1436 if (data->Sync[id].SyncPeriod != 0) {
1437 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1439 SPRINTF(" transfer %d.%dMB/s, offset %d",
1440 speed / 1000,
1441 speed % 1000,
1442 data->Sync[id].SyncOffset
1445 SPRINTF("\n");
1447 return 0;
1449 #undef SPRINTF
1451 /*---------------------------------------------------------------*/
1452 /* error handler */
1453 /*---------------------------------------------------------------*/
1456 static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1458 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1460 return nsp_eh_bus_reset(SCpnt);
1463 static int nsp_bus_reset(nsp_hw_data *data)
1465 unsigned int base = data->BaseAddress;
1466 int i;
1468 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1470 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1471 mdelay(100); /* 100ms */
1472 nsp_index_write(base, SCSIBUSCTRL, 0);
1473 for(i = 0; i < 5; i++) {
1474 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1477 nsphw_init_sync(data);
1479 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1481 return SUCCESS;
1484 static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1486 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1488 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1490 return nsp_bus_reset(data);
1493 static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1495 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1497 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1499 nsphw_init(data);
1501 return SUCCESS;
1505 /**********************************************************************
1506 PCMCIA functions
1507 **********************************************************************/
1509 static int nsp_cs_probe(struct pcmcia_device *link)
1511 scsi_info_t *info;
1512 nsp_hw_data *data = &nsp_data_base;
1513 int ret;
1515 nsp_dbg(NSP_DEBUG_INIT, "in");
1517 /* Create new SCSI device */
1518 info = kzalloc(sizeof(*info), GFP_KERNEL);
1519 if (info == NULL) { return -ENOMEM; }
1520 info->p_dev = link;
1521 link->priv = info;
1522 data->ScsiInfo = info;
1524 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1526 ret = nsp_cs_config(link);
1528 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1529 return ret;
1530 } /* nsp_cs_attach */
1533 static void nsp_cs_detach(struct pcmcia_device *link)
1535 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1537 ((scsi_info_t *)link->priv)->stop = 1;
1538 nsp_cs_release(link);
1540 kfree(link->priv);
1541 link->priv = NULL;
1542 } /* nsp_cs_detach */
1545 static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1547 nsp_hw_data *data = priv_data;
1549 if (p_dev->config_index == 0)
1550 return -ENODEV;
1552 /* This reserves IO space but doesn't actually enable it */
1553 if (pcmcia_request_io(p_dev) != 0)
1554 goto next_entry;
1556 if (resource_size(p_dev->resource[2])) {
1557 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1558 WIN_MEMORY_TYPE_CM |
1559 WIN_ENABLE);
1560 if (p_dev->resource[2]->end < 0x1000)
1561 p_dev->resource[2]->end = 0x1000;
1562 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1563 goto next_entry;
1564 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
1565 p_dev->card_addr) != 0)
1566 goto next_entry;
1568 data->MmioAddress = (unsigned long)
1569 ioremap_nocache(p_dev->resource[2]->start,
1570 resource_size(p_dev->resource[2]));
1571 data->MmioLength = resource_size(p_dev->resource[2]);
1573 /* If we got this far, we're cool! */
1574 return 0;
1576 next_entry:
1577 nsp_dbg(NSP_DEBUG_INIT, "next");
1578 pcmcia_disable_device(p_dev);
1579 return -ENODEV;
1582 static int nsp_cs_config(struct pcmcia_device *link)
1584 int ret;
1585 scsi_info_t *info = link->priv;
1586 struct Scsi_Host *host;
1587 nsp_hw_data *data = &nsp_data_base;
1589 nsp_dbg(NSP_DEBUG_INIT, "in");
1591 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1592 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1593 CONF_AUTO_SET_IO;
1595 ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
1596 if (ret)
1597 goto cs_failed;
1599 if (pcmcia_request_irq(link, nspintr))
1600 goto cs_failed;
1602 ret = pcmcia_enable_device(link);
1603 if (ret)
1604 goto cs_failed;
1606 if (free_ports) {
1607 if (link->resource[0]) {
1608 release_region(link->resource[0]->start,
1609 resource_size(link->resource[0]));
1611 if (link->resource[1]) {
1612 release_region(link->resource[1]->start,
1613 resource_size(link->resource[1]));
1617 /* Set port and IRQ */
1618 data->BaseAddress = link->resource[0]->start;
1619 data->NumAddress = resource_size(link->resource[0]);
1620 data->IrqNumber = link->irq;
1622 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1623 data->BaseAddress, data->NumAddress, data->IrqNumber);
1625 if(nsphw_init(data) == FALSE) {
1626 goto cs_failed;
1629 host = nsp_detect(&nsp_driver_template);
1631 if (host == NULL) {
1632 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1633 goto cs_failed;
1637 ret = scsi_add_host (host, NULL);
1638 if (ret)
1639 goto cs_failed;
1641 scsi_scan_host(host);
1643 info->host = host;
1645 return 0;
1647 cs_failed:
1648 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1649 nsp_cs_release(link);
1651 return -ENODEV;
1652 } /* nsp_cs_config */
1655 static void nsp_cs_release(struct pcmcia_device *link)
1657 scsi_info_t *info = link->priv;
1658 nsp_hw_data *data = NULL;
1660 if (info->host == NULL) {
1661 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1662 } else {
1663 data = (nsp_hw_data *)info->host->hostdata;
1666 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1668 /* Unlink the device chain */
1669 if (info->host != NULL) {
1670 scsi_remove_host(info->host);
1673 if (resource_size(link->resource[2])) {
1674 if (data != NULL) {
1675 iounmap((void *)(data->MmioAddress));
1678 pcmcia_disable_device(link);
1680 if (info->host != NULL) {
1681 scsi_host_put(info->host);
1683 } /* nsp_cs_release */
1685 static int nsp_cs_suspend(struct pcmcia_device *link)
1687 scsi_info_t *info = link->priv;
1688 nsp_hw_data *data;
1690 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1692 if (info->host != NULL) {
1693 nsp_msg(KERN_INFO, "clear SDTR status");
1695 data = (nsp_hw_data *)info->host->hostdata;
1697 nsphw_init_sync(data);
1700 info->stop = 1;
1702 return 0;
1705 static int nsp_cs_resume(struct pcmcia_device *link)
1707 scsi_info_t *info = link->priv;
1708 nsp_hw_data *data;
1710 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1712 info->stop = 0;
1714 if (info->host != NULL) {
1715 nsp_msg(KERN_INFO, "reset host and bus");
1717 data = (nsp_hw_data *)info->host->hostdata;
1719 nsphw_init (data);
1720 nsp_bus_reset(data);
1723 return 0;
1726 /*======================================================================*
1727 * module entry point
1728 *====================================================================*/
1729 static const struct pcmcia_device_id nsp_cs_ids[] = {
1730 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1731 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1732 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1733 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1734 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1735 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1736 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1737 PCMCIA_DEVICE_NULL
1739 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1741 static struct pcmcia_driver nsp_driver = {
1742 .owner = THIS_MODULE,
1743 .name = "nsp_cs",
1744 .probe = nsp_cs_probe,
1745 .remove = nsp_cs_detach,
1746 .id_table = nsp_cs_ids,
1747 .suspend = nsp_cs_suspend,
1748 .resume = nsp_cs_resume,
1751 static int __init nsp_cs_init(void)
1753 return pcmcia_register_driver(&nsp_driver);
1756 static void __exit nsp_cs_exit(void)
1758 pcmcia_unregister_driver(&nsp_driver);
1762 module_init(nsp_cs_init)
1763 module_exit(nsp_cs_exit)
1765 /* end */