1/*======================================================================
2
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
5
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
12
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
15
16======================================================================*/
17
18/***********************************************************************
19 This driver is for these PCcards.
20
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"
25
26***********************************************************************/
27
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>
40
41#include <asm/io.h>
42#include <asm/irq.h>
43
44#include <scsi/scsi.h>
45#include <scsi/scsi_cmnd.h>
46#include <scsi/scsi_host.h>
47#include <scsi/scsi_ioctl.h>
48
49#include <pcmcia/cistpl.h>
50#include <pcmcia/cisreg.h>
51#include <pcmcia/ds.h>
52
53#include "nsp_cs.h"
54
55MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
56MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
57MODULE_LICENSE("GPL");
58
59#include "nsp_io.h"
60
61/*====================================================================*/
62/* Parameters that can be set with 'insmod' */
63
64static int nsp_burst_mode = BURST_MEM32;
65module_param(nsp_burst_mode, int, 0);
66MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
67
68/* Release IO ports after configuration? */
69static bool free_ports = 0;
70module_param(free_ports, bool, 0);
71MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
72
73static struct scsi_pointer *nsp_priv(struct scsi_cmnd *cmd)
74{
75 return scsi_cmd_priv(cmd);
76}
77
78static struct scsi_host_template nsp_driver_template = {
79 .proc_name = "nsp_cs",
80 .show_info = nsp_show_info,
81 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
82 .info = nsp_info,
83 .queuecommand = nsp_queuecommand,
84/* .eh_abort_handler = nsp_eh_abort,*/
85 .eh_bus_reset_handler = nsp_eh_bus_reset,
86 .eh_host_reset_handler = nsp_eh_host_reset,
87 .can_queue = 1,
88 .this_id = NSP_INITIATOR_ID,
89 .sg_tablesize = SG_ALL,
90 .dma_boundary = PAGE_SIZE - 1,
91 .cmd_size = sizeof(struct scsi_pointer),
92};
93
94static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
95
96
97
98/*
99 * debug, error print
100 */
101#ifndef NSP_DEBUG
102# define NSP_DEBUG_MASK 0x000000
103# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
104# define nsp_dbg(mask, args...) /* */
105#else
106# define NSP_DEBUG_MASK 0xffffff
107# define nsp_msg(type, args...) \
108 nsp_cs_message (__func__, __LINE__, (type), args)
109# define nsp_dbg(mask, args...) \
110 nsp_cs_dmessage(__func__, __LINE__, (mask), args)
111#endif
112
113#define NSP_DEBUG_QUEUECOMMAND BIT(0)
114#define NSP_DEBUG_REGISTER BIT(1)
115#define NSP_DEBUG_AUTOSCSI BIT(2)
116#define NSP_DEBUG_INTR BIT(3)
117#define NSP_DEBUG_SGLIST BIT(4)
118#define NSP_DEBUG_BUSFREE BIT(5)
119#define NSP_DEBUG_CDB_CONTENTS BIT(6)
120#define NSP_DEBUG_RESELECTION BIT(7)
121#define NSP_DEBUG_MSGINOCCUR BIT(8)
122#define NSP_DEBUG_EEPROM BIT(9)
123#define NSP_DEBUG_MSGOUTOCCUR BIT(10)
124#define NSP_DEBUG_BUSRESET BIT(11)
125#define NSP_DEBUG_RESTART BIT(12)
126#define NSP_DEBUG_SYNC BIT(13)
127#define NSP_DEBUG_WAIT BIT(14)
128#define NSP_DEBUG_TARGETFLAG BIT(15)
129#define NSP_DEBUG_PROC BIT(16)
130#define NSP_DEBUG_INIT BIT(17)
131#define NSP_DEBUG_DATA_IO BIT(18)
132#define NSP_SPECIAL_PRINT_REGISTER BIT(20)
133
134#define NSP_DEBUG_BUF_LEN 150
135
136static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
137{
138 scsi_set_resid(cmd: SCpnt, resid: scsi_get_resid(cmd: SCpnt) + residInc);
139}
140
141__printf(4, 5)
142static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
143{
144 va_list args;
145 char buf[NSP_DEBUG_BUF_LEN];
146
147 va_start(args, fmt);
148 vsnprintf(buf, size: sizeof(buf), fmt, args);
149 va_end(args);
150
151#ifndef NSP_DEBUG
152 printk("%snsp_cs: %s\n", type, buf);
153#else
154 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
155#endif
156}
157
158#ifdef NSP_DEBUG
159static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
160{
161 va_list args;
162 char buf[NSP_DEBUG_BUF_LEN];
163
164 va_start(args, fmt);
165 vsnprintf(buf, sizeof(buf), fmt, args);
166 va_end(args);
167
168 if (mask & NSP_DEBUG_MASK) {
169 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
170 }
171}
172#endif
173
174/***********************************************************/
175
176/*====================================================
177 * Clenaup parameters and call done() functions.
178 * You must be set SCpnt->result before call this function.
179 */
180static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
181{
182 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
183
184 data->CurrentSC = NULL;
185
186 scsi_done(cmd: SCpnt);
187}
188
189static int nsp_queuecommand_lck(struct scsi_cmnd *const SCpnt)
190{
191 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
192#ifdef NSP_DEBUG
193 /*unsigned int host_id = SCpnt->device->host->this_id;*/
194 /*unsigned int base = SCpnt->device->host->io_port;*/
195 unsigned char target = scmd_id(SCpnt);
196#endif
197 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
198
199 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
200 "SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
201 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
202 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
203 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
204
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;
210 }
211
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;
220 }
221#endif
222
223 show_command(SCpnt);
224
225 data->CurrentSC = SCpnt;
226
227 scsi_pointer->Status = SAM_STAT_CHECK_CONDITION;
228 scsi_pointer->Message = 0;
229 scsi_pointer->have_data_in = IO_UNKNOWN;
230 scsi_pointer->sent_command = 0;
231 scsi_pointer->phase = PH_UNDETERMINED;
232 scsi_set_resid(cmd: SCpnt, resid: scsi_bufflen(cmd: SCpnt));
233
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(cmd: SCpnt)) {
241 scsi_pointer->buffer = scsi_sglist(cmd: SCpnt);
242 scsi_pointer->ptr = BUFFER_ADDR(SCpnt);
243 scsi_pointer->this_residual = scsi_pointer->buffer->length;
244 scsi_pointer->buffers_residual = scsi_sg_count(cmd: SCpnt) - 1;
245 } else {
246 scsi_pointer->ptr = NULL;
247 scsi_pointer->this_residual = 0;
248 scsi_pointer->buffer = NULL;
249 scsi_pointer->buffers_residual = 0;
250 }
251
252 if (!nsphw_start_selection(SCpnt)) {
253 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
254 SCpnt->result = DID_BUS_BUSY << 16;
255 nsp_scsi_done(SCpnt);
256 return 0;
257 }
258
259
260 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
261#ifdef NSP_DEBUG
262 data->CmdId++;
263#endif
264 return 0;
265}
266
267static DEF_SCSI_QCMD(nsp_queuecommand)
268
269/*
270 * setup PIO FIFO transfer mode and enable/disable to data out
271 */
272static void nsp_setup_fifo(nsp_hw_data *data, bool enabled)
273{
274 unsigned int base = data->BaseAddress;
275 unsigned char transfer_mode_reg;
276
277 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
278
279 if (enabled) {
280 transfer_mode_reg = TRANSFER_GO | BRAIND;
281 } else {
282 transfer_mode_reg = 0;
283 }
284
285 transfer_mode_reg |= data->TransferMode;
286
287 nsp_index_write(BaseAddr: base, TRANSFERMODE, Value: transfer_mode_reg);
288}
289
290static void nsphw_init_sync(nsp_hw_data *data)
291{
292 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
293 .SyncPeriod = 0,
294 .SyncOffset = 0
295 };
296 int i;
297
298 /* setup sync data */
299 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
300 data->Sync[i] = tmp_sync;
301 }
302}
303
304/*
305 * Initialize Ninja hardware
306 */
307static void nsphw_init(nsp_hw_data *data)
308{
309 unsigned int base = data->BaseAddress;
310
311 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
312
313 data->ScsiClockDiv = CLOCK_40M | FAST_20;
314 data->CurrentSC = NULL;
315 data->FifoCount = 0;
316 data->TransferMode = MODE_IO8;
317
318 nsphw_init_sync(data);
319
320 /* block all interrupts */
321 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
322
323 /* setup SCSI interface */
324 nsp_write(base, IFSELECT, IF_IFSEL);
325
326 nsp_index_write(BaseAddr: base, SCSIIRQMODE, Value: 0);
327
328 nsp_index_write(BaseAddr: base, TRANSFERMODE, MODE_IO8);
329 nsp_index_write(BaseAddr: base, CLOCKDIV, Value: data->ScsiClockDiv);
330
331 nsp_index_write(BaseAddr: base, PARITYCTRL, Value: 0);
332 nsp_index_write(BaseAddr: base, POINTERCLR, POINTER_CLEAR |
333 ACK_COUNTER_CLEAR |
334 REQ_COUNTER_CLEAR |
335 HOST_COUNTER_CLEAR);
336
337 /* setup fifo asic */
338 nsp_write(base, IFSELECT, IF_REGSEL);
339 nsp_index_write(BaseAddr: base, TERMPWRCTRL, Value: 0);
340 if ((nsp_index_read(BaseAddr: base, OTHERCONTROL) & TPWR_SENSE) == 0) {
341 nsp_msg(KERN_INFO, "terminator power on");
342 nsp_index_write(BaseAddr: base, TERMPWRCTRL, POWER_ON);
343 }
344
345 nsp_index_write(BaseAddr: base, TIMERCOUNT, Value: 0);
346 nsp_index_write(BaseAddr: base, TIMERCOUNT, Value: 0); /* requires 2 times!! */
347
348 nsp_index_write(BaseAddr: base, SYNCREG, Value: 0);
349 nsp_index_write(BaseAddr: base, ACKWIDTH, Value: 0);
350
351 /* enable interrupts and ack them */
352 nsp_index_write(BaseAddr: base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
353 RESELECT_EI |
354 SCSI_RESET_IRQ_EI );
355 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
356
357 nsp_setup_fifo(data, enabled: false);
358}
359
360/*
361 * Start selection phase
362 */
363static bool nsphw_start_selection(struct scsi_cmnd *const SCpnt)
364{
365 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
366 unsigned int host_id = SCpnt->device->host->this_id;
367 unsigned int base = SCpnt->device->host->io_port;
368 unsigned char target = scmd_id(SCpnt);
369 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
370 int time_out;
371 unsigned char phase, arbit;
372
373 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
374
375 phase = nsp_index_read(BaseAddr: base, SCSIBUSMON);
376 if(phase != BUSMON_BUS_FREE) {
377 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
378 return false;
379 }
380
381 /* start arbitration */
382 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
383 scsi_pointer->phase = PH_ARBSTART;
384 nsp_index_write(BaseAddr: base, SETARBIT, ARBIT_GO);
385
386 time_out = 1000;
387 do {
388 /* XXX: what a stupid chip! */
389 arbit = nsp_index_read(BaseAddr: base, ARBITSTATUS);
390 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
391 udelay(1); /* hold 1.2us */
392 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
393 (time_out-- != 0));
394
395 if (!(arbit & ARBIT_WIN)) {
396 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
397 nsp_index_write(BaseAddr: base, SETARBIT, ARBIT_FLAG_CLEAR);
398 return false;
399 }
400
401 /* assert select line */
402 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
403 scsi_pointer->phase = PH_SELSTART;
404 udelay(3); /* wait 2.4us */
405 nsp_index_write(BaseAddr: base, SCSIDATALATCH, BIT(host_id) | BIT(target));
406 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
407 udelay(2); /* wait >1.2us */
408 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
409 nsp_index_write(BaseAddr: base, SETARBIT, ARBIT_FLAG_CLEAR);
410 /*udelay(1);*/ /* wait >90ns */
411 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
412
413 /* check selection timeout */
414 nsp_start_timer(SCpnt, time: 1000/51);
415 data->SelectionTimeOut = 1;
416
417 return true;
418}
419
420struct nsp_sync_table {
421 unsigned int min_period;
422 unsigned int max_period;
423 unsigned int chip_period;
424 unsigned int ack_width;
425};
426
427static struct nsp_sync_table nsp_sync_table_40M[] = {
428 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
429 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
430 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
431 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
432 { 0, 0, 0, 0},
433};
434
435static struct nsp_sync_table nsp_sync_table_20M[] = {
436 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
437 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
438 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
439 { 0, 0, 0, 0},
440};
441
442/*
443 * setup synchronous data transfer mode
444 */
445static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
446{
447 unsigned char target = scmd_id(SCpnt);
448// unsigned char lun = SCpnt->device->lun;
449 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
450 sync_data *sync = &(data->Sync[target]);
451 struct nsp_sync_table *sync_table;
452 unsigned int period, offset;
453
454 nsp_dbg(NSP_DEBUG_SYNC, "in");
455
456 period = sync->SyncPeriod;
457 offset = sync->SyncOffset;
458
459 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
460
461 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
462 sync_table = nsp_sync_table_20M;
463 } else {
464 sync_table = nsp_sync_table_40M;
465 }
466
467 for (; sync_table->max_period != 0; sync_table++) {
468 if ( period >= sync_table->min_period &&
469 period <= sync_table->max_period ) {
470 break;
471 }
472 }
473
474 if (period != 0 && sync_table->max_period == 0) {
475 /*
476 * No proper period/offset found
477 */
478 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
479
480 sync->SyncPeriod = 0;
481 sync->SyncOffset = 0;
482 sync->SyncRegister = 0;
483 sync->AckWidth = 0;
484
485 return false;
486 }
487
488 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
489 (offset & SYNCREG_OFFSET_MASK);
490 sync->AckWidth = sync_table->ack_width;
491
492 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
493
494 return true;
495}
496
497
498/*
499 * start ninja hardware timer
500 */
501static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
502{
503 unsigned int base = SCpnt->device->host->io_port;
504 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
505
506 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
507 data->TimerCount = time;
508 nsp_index_write(BaseAddr: base, TIMERCOUNT, Value: time);
509}
510
511/*
512 * wait for bus phase change
513 */
514static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
515 char *str)
516{
517 unsigned int base = SCpnt->device->host->io_port;
518 unsigned char reg;
519 int time_out;
520
521 //nsp_dbg(NSP_DEBUG_INTR, "in");
522
523 time_out = 100;
524
525 do {
526 reg = nsp_index_read(BaseAddr: base, SCSIBUSMON);
527 if (reg == 0xff) {
528 break;
529 }
530 } while ((--time_out != 0) && (reg & mask) != 0);
531
532 if (time_out == 0) {
533 nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
534 }
535
536 return 0;
537}
538
539/*
540 * expect Ninja Irq
541 */
542static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
543 unsigned char current_phase,
544 unsigned char mask)
545{
546 unsigned int base = SCpnt->device->host->io_port;
547 int time_out;
548 unsigned char phase, i_src;
549
550 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
551
552 time_out = 100;
553 do {
554 phase = nsp_index_read(BaseAddr: base, SCSIBUSMON);
555 if (phase == 0xff) {
556 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
557 return -1;
558 }
559 i_src = nsp_read(base, IRQSTATUS);
560 if (i_src & IRQSTATUS_SCSI) {
561 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
562 return 0;
563 }
564 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
565 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
566 return 1;
567 }
568 } while(time_out-- != 0);
569
570 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
571 return -1;
572}
573
574/*
575 * transfer SCSI message
576 */
577static int nsp_xfer(struct scsi_cmnd *const SCpnt, int phase)
578{
579 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
580 unsigned int base = SCpnt->device->host->io_port;
581 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
582 char *buf = data->MsgBuffer;
583 int len = min(MSGBUF_SIZE, data->MsgLen);
584 int ptr;
585 int ret;
586
587 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
588 for (ptr = 0; len > 0; len--, ptr++) {
589
590 ret = nsp_expect_signal(SCpnt, current_phase: phase, BUSMON_REQ);
591 if (ret <= 0) {
592 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
593 return 0;
594 }
595
596 /* if last byte, negate ATN */
597 if (len == 1 && scsi_pointer->phase == PH_MSG_OUT) {
598 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
599 }
600
601 /* read & write message */
602 if (phase & BUSMON_IO) {
603 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
604 buf[ptr] = nsp_index_read(BaseAddr: base, SCSIDATAWITHACK);
605 } else {
606 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
607 nsp_index_write(BaseAddr: base, SCSIDATAWITHACK, Value: buf[ptr]);
608 }
609 nsp_negate_signal(SCpnt, BUSMON_ACK, str: "xfer<ack>");
610
611 }
612 return len;
613}
614
615/*
616 * get extra SCSI data from fifo
617 */
618static int nsp_dataphase_bypass(struct scsi_cmnd *const SCpnt)
619{
620 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
621 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
622 unsigned int count;
623
624 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
625
626 if (scsi_pointer->have_data_in != IO_IN) {
627 return 0;
628 }
629
630 count = nsp_fifo_count(SCpnt);
631 if (data->FifoCount == count) {
632 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
633 return 0;
634 }
635
636 /*
637 * XXX: NSP_QUIRK
638 * data phase skip only occures in case of SCSI_LOW_READ
639 */
640 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
641 scsi_pointer->phase = PH_DATA;
642 nsp_pio_read(SCpnt);
643 nsp_setup_fifo(data, enabled: false);
644
645 return 0;
646}
647
648/*
649 * accept reselection
650 */
651static void nsp_reselected(struct scsi_cmnd *SCpnt)
652{
653 unsigned int base = SCpnt->device->host->io_port;
654 unsigned int host_id = SCpnt->device->host->this_id;
655 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
656 unsigned char bus_reg;
657 unsigned char id_reg, tmp;
658 int target;
659
660 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
661
662 id_reg = nsp_index_read(BaseAddr: base, RESELECTID);
663 tmp = id_reg & (~BIT(host_id));
664 target = 0;
665 while(tmp != 0) {
666 if (tmp & BIT(0)) {
667 break;
668 }
669 tmp >>= 1;
670 target++;
671 }
672
673 if (scmd_id(SCpnt) != target) {
674 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
675 }
676
677 nsp_negate_signal(SCpnt, BUSMON_SEL, str: "reselect<SEL>");
678
679 nsp_nexus(SCpnt);
680 bus_reg = nsp_index_read(BaseAddr: base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
681 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, Value: bus_reg);
682 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, Value: bus_reg | AUTODIRECTION | ACKENB);
683}
684
685/*
686 * count how many data transferd
687 */
688static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
689{
690 unsigned int base = SCpnt->device->host->io_port;
691 unsigned int count;
692 unsigned int l, m, h;
693
694 nsp_index_write(BaseAddr: base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
695
696 l = nsp_index_read(BaseAddr: base, TRANSFERCOUNT);
697 m = nsp_index_read(BaseAddr: base, TRANSFERCOUNT);
698 h = nsp_index_read(BaseAddr: base, TRANSFERCOUNT);
699 nsp_index_read(BaseAddr: base, TRANSFERCOUNT); /* required this! */
700
701 count = (h << 16) | (m << 8) | (l << 0);
702
703 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
704
705 return count;
706}
707
708/* fifo size */
709#define RFIFO_CRIT 64
710#define WFIFO_CRIT 64
711
712/*
713 * read data in DATA IN phase
714 */
715static void nsp_pio_read(struct scsi_cmnd *const SCpnt)
716{
717 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
718 unsigned int base = SCpnt->device->host->io_port;
719 unsigned long mmio_base = SCpnt->device->host->base;
720 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
721 long time_out;
722 int ocount, res;
723 unsigned char stat, fifo_stat;
724
725 ocount = data->FifoCount;
726
727 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",
728 SCpnt, scsi_get_resid(SCpnt), ocount, scsi_pointer->ptr,
729 scsi_pointer->this_residual, scsi_pointer->buffer,
730 scsi_pointer->buffers_residual);
731
732 time_out = 1000;
733
734 while ((time_out-- != 0) &&
735 (scsi_pointer->this_residual > 0 ||
736 scsi_pointer->buffers_residual > 0)) {
737
738 stat = nsp_index_read(BaseAddr: base, SCSIBUSMON);
739 stat &= BUSMON_PHASE_MASK;
740
741
742 res = nsp_fifo_count(SCpnt) - ocount;
743 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, ocount, res);
744 if (res == 0) { /* if some data available ? */
745 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
746 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", scsi_pointer->this_residual);
747 continue;
748 } else {
749 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
750 break;
751 }
752 }
753
754 fifo_stat = nsp_read(base, FIFOSTATUS);
755 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
756 stat == BUSPHASE_DATA_IN) {
757 continue;
758 }
759
760 res = min(res, scsi_pointer->this_residual);
761
762 switch (data->TransferMode) {
763 case MODE_IO32:
764 res &= ~(BIT(1)|BIT(0)); /* align 4 */
765 nsp_fifo32_read(base, buf: scsi_pointer->ptr, count: res >> 2);
766 break;
767 case MODE_IO8:
768 nsp_fifo8_read(base, buf: scsi_pointer->ptr, count: res);
769 break;
770
771 case MODE_MEM32:
772 res &= ~(BIT(1)|BIT(0)); /* align 4 */
773 nsp_mmio_fifo32_read(base: mmio_base, buf: scsi_pointer->ptr,
774 count: res >> 2);
775 break;
776
777 default:
778 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
779 return;
780 }
781
782 nsp_inc_resid(SCpnt, residInc: -res);
783 scsi_pointer->ptr += res;
784 scsi_pointer->this_residual -= res;
785 ocount += res;
786 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, ocount);
787
788 /* go to next scatter list if available */
789 if (scsi_pointer->this_residual == 0 &&
790 scsi_pointer->buffers_residual != 0 ) {
791 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
792 scsi_pointer->buffers_residual--;
793 scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
794 scsi_pointer->ptr = BUFFER_ADDR(SCpnt);
795 scsi_pointer->this_residual =
796 scsi_pointer->buffer->length;
797 time_out = 1000;
798
799 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", scsi_pointer->buffer->page, scsi_pointer->buffer->offset);
800 }
801 }
802
803 data->FifoCount = ocount;
804
805 if (time_out < 0) {
806 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
807 scsi_get_resid(SCpnt), scsi_pointer->this_residual,
808 scsi_pointer->buffers_residual);
809 }
810 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
811 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
812 scsi_get_resid(SCpnt));
813}
814
815/*
816 * write data in DATA OUT phase
817 */
818static void nsp_pio_write(struct scsi_cmnd *SCpnt)
819{
820 struct scsi_pointer *scsi_pointer = nsp_priv(cmd: SCpnt);
821 unsigned int base = SCpnt->device->host->io_port;
822 unsigned long mmio_base = SCpnt->device->host->base;
823 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
824 int time_out;
825 int ocount, res;
826 unsigned char stat;
827
828 ocount = data->FifoCount;
829
830 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
831 data->FifoCount, scsi_pointer->ptr, scsi_pointer->this_residual,
832 scsi_pointer->buffer, scsi_pointer->buffers_residual,
833 scsi_get_resid(SCpnt));
834
835 time_out = 1000;
836
837 while ((time_out-- != 0) &&
838 (scsi_pointer->this_residual > 0 ||
839 scsi_pointer->buffers_residual > 0)) {
840 stat = nsp_index_read(BaseAddr: base, SCSIBUSMON);
841 stat &= BUSMON_PHASE_MASK;
842
843 if (stat != BUSPHASE_DATA_OUT) {
844 res = ocount - nsp_fifo_count(SCpnt);
845
846 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
847 /* Put back pointer */
848 nsp_inc_resid(SCpnt, residInc: res);
849 scsi_pointer->ptr -= res;
850 scsi_pointer->this_residual += res;
851 ocount -= res;
852
853 break;
854 }
855
856 res = ocount - nsp_fifo_count(SCpnt);
857 if (res > 0) { /* write all data? */
858 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
859 continue;
860 }
861
862 res = min(scsi_pointer->this_residual, WFIFO_CRIT);
863
864 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", scsi_pointer->ptr, scsi_pointer->this_residual, res);
865 switch (data->TransferMode) {
866 case MODE_IO32:
867 res &= ~(BIT(1)|BIT(0)); /* align 4 */
868 nsp_fifo32_write(base, buf: scsi_pointer->ptr, count: res >> 2);
869 break;
870 case MODE_IO8:
871 nsp_fifo8_write(base, buf: scsi_pointer->ptr, count: res);
872 break;
873
874 case MODE_MEM32:
875 res &= ~(BIT(1)|BIT(0)); /* align 4 */
876 nsp_mmio_fifo32_write(base: mmio_base, buf: scsi_pointer->ptr,
877 count: res >> 2);
878 break;
879
880 default:
881 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
882 break;
883 }
884
885 nsp_inc_resid(SCpnt, residInc: -res);
886 scsi_pointer->ptr += res;
887 scsi_pointer->this_residual -= res;
888 ocount += res;
889
890 /* go to next scatter list if available */
891 if (scsi_pointer->this_residual == 0 &&
892 scsi_pointer->buffers_residual != 0 ) {
893 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
894 scsi_pointer->buffers_residual--;
895 scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
896 scsi_pointer->ptr = BUFFER_ADDR(SCpnt);
897 scsi_pointer->this_residual =
898 scsi_pointer->buffer->length;
899 time_out = 1000;
900 }
901 }
902
903 data->FifoCount = ocount;
904
905 if (time_out < 0) {
906 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
907 scsi_get_resid(SCpnt));
908 }
909 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
910 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
911 scsi_get_resid(SCpnt));
912}
913#undef RFIFO_CRIT
914#undef WFIFO_CRIT
915
916/*
917 * setup synchronous/asynchronous data transfer mode
918 */
919static int nsp_nexus(struct scsi_cmnd *SCpnt)
920{
921 unsigned int base = SCpnt->device->host->io_port;
922 unsigned char target = scmd_id(SCpnt);
923// unsigned char lun = SCpnt->device->lun;
924 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
925 sync_data *sync = &(data->Sync[target]);
926
927 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
928
929 /* setup synch transfer registers */
930 nsp_index_write(BaseAddr: base, SYNCREG, Value: sync->SyncRegister);
931 nsp_index_write(BaseAddr: base, ACKWIDTH, Value: sync->AckWidth);
932
933 if (scsi_get_resid(cmd: SCpnt) % 4 != 0 ||
934 scsi_get_resid(cmd: SCpnt) <= PAGE_SIZE ) {
935 data->TransferMode = MODE_IO8;
936 } else if (nsp_burst_mode == BURST_MEM32) {
937 data->TransferMode = MODE_MEM32;
938 } else if (nsp_burst_mode == BURST_IO32) {
939 data->TransferMode = MODE_IO32;
940 } else {
941 data->TransferMode = MODE_IO8;
942 }
943
944 /* setup pdma fifo */
945 nsp_setup_fifo(data, enabled: true);
946
947 /* clear ack counter */
948 data->FifoCount = 0;
949 nsp_index_write(BaseAddr: base, POINTERCLR, POINTER_CLEAR |
950 ACK_COUNTER_CLEAR |
951 REQ_COUNTER_CLEAR |
952 HOST_COUNTER_CLEAR);
953
954 return 0;
955}
956
957#include "nsp_message.c"
958/*
959 * interrupt handler
960 */
961static irqreturn_t nspintr(int irq, void *dev_id)
962{
963 unsigned int base;
964 unsigned char irq_status, irq_phase, phase;
965 struct scsi_cmnd *tmpSC;
966 struct scsi_pointer *scsi_pointer;
967 unsigned char target, lun;
968 unsigned int *sync_neg;
969 int i, tmp;
970 nsp_hw_data *data;
971
972
973 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
974 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
975
976 if ( dev_id != NULL &&
977 ((scsi_info_t *)dev_id)->host != NULL ) {
978 scsi_info_t *info = (scsi_info_t *)dev_id;
979
980 data = (nsp_hw_data *)info->host->hostdata;
981 } else {
982 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
983 return IRQ_NONE;
984 }
985
986 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
987
988 base = data->BaseAddress;
989 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
990
991 /*
992 * interrupt check
993 */
994 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
995 irq_status = nsp_read(base, IRQSTATUS);
996 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
997 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
998 nsp_write(base, IRQCONTROL, val: 0);
999 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
1000 return IRQ_NONE;
1001 }
1002
1003 /* XXX: IMPORTANT
1004 * Do not read an irq_phase register if no scsi phase interrupt.
1005 * Unless, you should lose a scsi phase interrupt.
1006 */
1007 phase = nsp_index_read(BaseAddr: base, SCSIBUSMON);
1008 if((irq_status & IRQSTATUS_SCSI) != 0) {
1009 irq_phase = nsp_index_read(BaseAddr: base, IRQPHASESENCE);
1010 } else {
1011 irq_phase = 0;
1012 }
1013
1014 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1015
1016 /*
1017 * timer interrupt handler (scsi vs timer interrupts)
1018 */
1019 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1020 if (data->TimerCount != 0) {
1021 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1022 nsp_index_write(BaseAddr: base, TIMERCOUNT, Value: 0);
1023 nsp_index_write(BaseAddr: base, TIMERCOUNT, Value: 0);
1024 data->TimerCount = 0;
1025 }
1026
1027 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1028 data->SelectionTimeOut == 0) {
1029 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1030 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1031 return IRQ_HANDLED;
1032 }
1033
1034 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1035
1036 if ((irq_status & IRQSTATUS_SCSI) &&
1037 (irq_phase & SCSI_RESET_IRQ)) {
1038 nsp_msg(KERN_ERR, "bus reset (power off?)");
1039
1040 nsphw_init(data);
1041 nsp_bus_reset(data);
1042
1043 if(data->CurrentSC != NULL) {
1044 tmpSC = data->CurrentSC;
1045 scsi_pointer = nsp_priv(cmd: tmpSC);
1046 tmpSC->result = (DID_RESET << 16) |
1047 ((scsi_pointer->Message & 0xff) << 8) |
1048 ((scsi_pointer->Status & 0xff) << 0);
1049 nsp_scsi_done(SCpnt: tmpSC);
1050 }
1051 return IRQ_HANDLED;
1052 }
1053
1054 if (data->CurrentSC == NULL) {
1055 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);
1056 nsphw_init(data);
1057 nsp_bus_reset(data);
1058 return IRQ_HANDLED;
1059 }
1060
1061 tmpSC = data->CurrentSC;
1062 scsi_pointer = nsp_priv(cmd: tmpSC);
1063 target = tmpSC->device->id;
1064 lun = tmpSC->device->lun;
1065 sync_neg = &(data->Sync[target].SyncNegotiation);
1066
1067 /*
1068 * parse hardware SCSI irq reasons register
1069 */
1070 if (irq_status & IRQSTATUS_SCSI) {
1071 if (irq_phase & RESELECT_IRQ) {
1072 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1073 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1074 nsp_reselected(SCpnt: tmpSC);
1075 return IRQ_HANDLED;
1076 }
1077
1078 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1079 return IRQ_HANDLED;
1080 }
1081 }
1082
1083 //show_phase(tmpSC);
1084
1085 switch (scsi_pointer->phase) {
1086 case PH_SELSTART:
1087 // *sync_neg = SYNC_NOT_YET;
1088 if ((phase & BUSMON_BSY) == 0) {
1089 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1090 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1091 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1092 data->SelectionTimeOut = 0;
1093 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, Value: 0);
1094
1095 tmpSC->result = DID_TIME_OUT << 16;
1096 nsp_scsi_done(SCpnt: tmpSC);
1097
1098 return IRQ_HANDLED;
1099 }
1100 data->SelectionTimeOut += 1;
1101 nsp_start_timer(SCpnt: tmpSC, time: 1000/51);
1102 return IRQ_HANDLED;
1103 }
1104
1105 /* attention assert */
1106 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1107 data->SelectionTimeOut = 0;
1108 scsi_pointer->phase = PH_SELECTED;
1109 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_ATN);
1110 udelay(1);
1111 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1112 return IRQ_HANDLED;
1113
1114 case PH_RESELECT:
1115 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1116 // *sync_neg = SYNC_NOT_YET;
1117 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1118
1119 tmpSC->result = DID_ABORT << 16;
1120 nsp_scsi_done(SCpnt: tmpSC);
1121 return IRQ_HANDLED;
1122 }
1123 fallthrough;
1124 default:
1125 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1126 return IRQ_HANDLED;
1127 }
1128 break;
1129 }
1130
1131 /*
1132 * SCSI sequencer
1133 */
1134 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1135
1136 /* normal disconnect */
1137 if ((scsi_pointer->phase == PH_MSG_IN ||
1138 scsi_pointer->phase == PH_MSG_OUT) &&
1139 (irq_phase & LATCHED_BUS_FREE) != 0) {
1140 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1141
1142 //*sync_neg = SYNC_NOT_YET;
1143
1144 /* all command complete and return status */
1145 if (scsi_pointer->Message == COMMAND_COMPLETE) {
1146 tmpSC->result = (DID_OK << 16) |
1147 ((scsi_pointer->Message & 0xff) << 8) |
1148 ((scsi_pointer->Status & 0xff) << 0);
1149 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1150 nsp_scsi_done(SCpnt: tmpSC);
1151
1152 return IRQ_HANDLED;
1153 }
1154
1155 return IRQ_HANDLED;
1156 }
1157
1158
1159 /* check unexpected bus free state */
1160 if (phase == 0) {
1161 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1162
1163 *sync_neg = SYNC_NG;
1164 tmpSC->result = DID_ERROR << 16;
1165 nsp_scsi_done(SCpnt: tmpSC);
1166 return IRQ_HANDLED;
1167 }
1168
1169 switch (phase & BUSMON_PHASE_MASK) {
1170 case BUSPHASE_COMMAND:
1171 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1172 if ((phase & BUSMON_REQ) == 0) {
1173 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1174 return IRQ_HANDLED;
1175 }
1176
1177 scsi_pointer->phase = PH_COMMAND;
1178
1179 nsp_nexus(SCpnt: tmpSC);
1180
1181 /* write scsi command */
1182 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1183 nsp_index_write(BaseAddr: base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1184 for (i = 0; i < tmpSC->cmd_len; i++) {
1185 nsp_index_write(BaseAddr: base, COMMANDDATA, Value: tmpSC->cmnd[i]);
1186 }
1187 nsp_index_write(BaseAddr: base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1188 break;
1189
1190 case BUSPHASE_DATA_OUT:
1191 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1192
1193 scsi_pointer->phase = PH_DATA;
1194 scsi_pointer->have_data_in = IO_OUT;
1195
1196 nsp_pio_write(SCpnt: tmpSC);
1197
1198 break;
1199
1200 case BUSPHASE_DATA_IN:
1201 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1202
1203 scsi_pointer->phase = PH_DATA;
1204 scsi_pointer->have_data_in = IO_IN;
1205
1206 nsp_pio_read(SCpnt: tmpSC);
1207
1208 break;
1209
1210 case BUSPHASE_STATUS:
1211 nsp_dataphase_bypass(SCpnt: tmpSC);
1212 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1213
1214 scsi_pointer->phase = PH_STATUS;
1215
1216 scsi_pointer->Status = nsp_index_read(BaseAddr: base, SCSIDATAWITHACK);
1217 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x",
1218 scsi_pointer->Message, scsi_pointer->Status);
1219
1220 break;
1221
1222 case BUSPHASE_MESSAGE_OUT:
1223 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1224 if ((phase & BUSMON_REQ) == 0) {
1225 goto timer_out;
1226 }
1227
1228 scsi_pointer->phase = PH_MSG_OUT;
1229
1230 //*sync_neg = SYNC_NOT_YET;
1231
1232 data->MsgLen = i = 0;
1233 data->MsgBuffer[i] = IDENTIFY(true, lun); i++;
1234
1235 if (*sync_neg == SYNC_NOT_YET) {
1236 data->Sync[target].SyncPeriod = 0;
1237 data->Sync[target].SyncOffset = 0;
1238
1239 /**/
1240 data->MsgBuffer[i] = EXTENDED_MESSAGE; i++;
1241 data->MsgBuffer[i] = 3; i++;
1242 data->MsgBuffer[i] = EXTENDED_SDTR; i++;
1243 data->MsgBuffer[i] = 0x0c; i++;
1244 data->MsgBuffer[i] = 15; i++;
1245 /**/
1246 }
1247 data->MsgLen = i;
1248
1249 nsp_analyze_sdtr(SCpnt: tmpSC);
1250 show_message(data);
1251 nsp_message_out(SCpnt: tmpSC);
1252 break;
1253
1254 case BUSPHASE_MESSAGE_IN:
1255 nsp_dataphase_bypass(SCpnt: tmpSC);
1256 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1257 if ((phase & BUSMON_REQ) == 0) {
1258 goto timer_out;
1259 }
1260
1261 scsi_pointer->phase = PH_MSG_IN;
1262 nsp_message_in(SCpnt: tmpSC);
1263
1264 /**/
1265 if (*sync_neg == SYNC_NOT_YET) {
1266 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1267
1268 if (data->MsgLen >= 5 &&
1269 data->MsgBuffer[0] == EXTENDED_MESSAGE &&
1270 data->MsgBuffer[1] == 3 &&
1271 data->MsgBuffer[2] == EXTENDED_SDTR ) {
1272 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1273 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1274 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1275 *sync_neg = SYNC_OK;
1276 } else {
1277 data->Sync[target].SyncPeriod = 0;
1278 data->Sync[target].SyncOffset = 0;
1279 *sync_neg = SYNC_NG;
1280 }
1281 nsp_analyze_sdtr(SCpnt: tmpSC);
1282 }
1283 /**/
1284
1285 /* search last messeage byte */
1286 tmp = -1;
1287 for (i = 0; i < data->MsgLen; i++) {
1288 tmp = data->MsgBuffer[i];
1289 if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
1290 i += (1 + data->MsgBuffer[i+1]);
1291 }
1292 }
1293 scsi_pointer->Message = tmp;
1294
1295 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d",
1296 scsi_pointer->Message, data->MsgLen);
1297 show_message(data);
1298
1299 break;
1300
1301 case BUSPHASE_SELECT:
1302 default:
1303 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1304
1305 break;
1306 }
1307
1308 //nsp_dbg(NSP_DEBUG_INTR, "out");
1309 return IRQ_HANDLED;
1310
1311timer_out:
1312 nsp_start_timer(SCpnt: tmpSC, time: 1000/102);
1313 return IRQ_HANDLED;
1314}
1315
1316#ifdef NSP_DEBUG
1317#include "nsp_debug.c"
1318#endif /* NSP_DEBUG */
1319
1320/*----------------------------------------------------------------*/
1321/* look for ninja3 card and init if found */
1322/*----------------------------------------------------------------*/
1323static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1324{
1325 struct Scsi_Host *host; /* registered host structure */
1326 nsp_hw_data *data_b = &nsp_data_base, *data;
1327
1328 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1329 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1330 if (host == NULL) {
1331 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1332 return NULL;
1333 }
1334
1335 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1336 data = (nsp_hw_data *)host->hostdata;
1337 data->ScsiInfo->host = host;
1338#ifdef NSP_DEBUG
1339 data->CmdId = 0;
1340#endif
1341
1342 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1343
1344 host->unique_id = data->BaseAddress;
1345 host->io_port = data->BaseAddress;
1346 host->n_io_port = data->NumAddress;
1347 host->irq = data->IrqNumber;
1348 host->base = data->MmioAddress;
1349
1350 spin_lock_init(&(data->Lock));
1351
1352 snprintf(buf: data->nspinfo,
1353 size: sizeof(data->nspinfo),
1354 fmt: "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1355 host->io_port, host->io_port + host->n_io_port - 1,
1356 host->base,
1357 host->irq);
1358 sht->name = data->nspinfo;
1359
1360 nsp_dbg(NSP_DEBUG_INIT, "end");
1361
1362
1363 return host; /* detect done. */
1364}
1365
1366/*----------------------------------------------------------------*/
1367/* return info string */
1368/*----------------------------------------------------------------*/
1369static const char *nsp_info(struct Scsi_Host *shpnt)
1370{
1371 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1372
1373 return data->nspinfo;
1374}
1375
1376static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1377{
1378 int id;
1379 int speed;
1380 unsigned long flags;
1381 nsp_hw_data *data;
1382 int hostno;
1383
1384 hostno = host->host_no;
1385 data = (nsp_hw_data *)host->hostdata;
1386
1387 seq_puts(m, s: "NinjaSCSI status\n\n"
1388 "Driver version: $Revision: 1.23 $\n");
1389 seq_printf(m, fmt: "SCSI host No.: %d\n", hostno);
1390 seq_printf(m, fmt: "IRQ: %d\n", host->irq);
1391 seq_printf(m, fmt: "IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1392 seq_printf(m, fmt: "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1393 seq_printf(m, fmt: "sg_tablesize: %d\n", host->sg_tablesize);
1394
1395 seq_puts(m, s: "burst transfer mode: ");
1396 switch (nsp_burst_mode) {
1397 case BURST_IO8:
1398 seq_puts(m, s: "io8");
1399 break;
1400 case BURST_IO32:
1401 seq_puts(m, s: "io32");
1402 break;
1403 case BURST_MEM32:
1404 seq_puts(m, s: "mem32");
1405 break;
1406 default:
1407 seq_puts(m, s: "???");
1408 break;
1409 }
1410 seq_putc(m, c: '\n');
1411
1412
1413 spin_lock_irqsave(&(data->Lock), flags);
1414 seq_printf(m, fmt: "CurrentSC: 0x%p\n\n", data->CurrentSC);
1415 spin_unlock_irqrestore(lock: &(data->Lock), flags);
1416
1417 seq_puts(m, s: "SDTR status\n");
1418 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1419
1420 seq_printf(m, fmt: "id %d: ", id);
1421
1422 if (id == host->this_id) {
1423 seq_puts(m, s: "----- NinjaSCSI-3 host adapter\n");
1424 continue;
1425 }
1426
1427 switch(data->Sync[id].SyncNegotiation) {
1428 case SYNC_OK:
1429 seq_puts(m, s: " sync");
1430 break;
1431 case SYNC_NG:
1432 seq_puts(m, s: "async");
1433 break;
1434 case SYNC_NOT_YET:
1435 seq_puts(m, s: " none");
1436 break;
1437 default:
1438 seq_puts(m, s: "?????");
1439 break;
1440 }
1441
1442 if (data->Sync[id].SyncPeriod != 0) {
1443 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1444
1445 seq_printf(m, fmt: " transfer %d.%dMB/s, offset %d",
1446 speed / 1000,
1447 speed % 1000,
1448 data->Sync[id].SyncOffset
1449 );
1450 }
1451 seq_putc(m, c: '\n');
1452 }
1453 return 0;
1454}
1455
1456/*---------------------------------------------------------------*/
1457/* error handler */
1458/*---------------------------------------------------------------*/
1459
1460/*
1461static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1462{
1463 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1464
1465 return nsp_eh_bus_reset(SCpnt);
1466}*/
1467
1468static int nsp_bus_reset(nsp_hw_data *data)
1469{
1470 unsigned int base = data->BaseAddress;
1471 int i;
1472
1473 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1474
1475 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, SCSI_RST);
1476 mdelay(100); /* 100ms */
1477 nsp_index_write(BaseAddr: base, SCSIBUSCTRL, Value: 0);
1478 for(i = 0; i < 5; i++) {
1479 nsp_index_read(BaseAddr: base, IRQPHASESENCE); /* dummy read */
1480 }
1481
1482 nsphw_init_sync(data);
1483
1484 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1485
1486 return SUCCESS;
1487}
1488
1489static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1490{
1491 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1492
1493 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1494
1495 return nsp_bus_reset(data);
1496}
1497
1498static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1499{
1500 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1501
1502 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1503
1504 nsphw_init(data);
1505
1506 return SUCCESS;
1507}
1508
1509
1510/**********************************************************************
1511 PCMCIA functions
1512**********************************************************************/
1513
1514static int nsp_cs_probe(struct pcmcia_device *link)
1515{
1516 scsi_info_t *info;
1517 nsp_hw_data *data = &nsp_data_base;
1518 int ret;
1519
1520 nsp_dbg(NSP_DEBUG_INIT, "in");
1521
1522 /* Create new SCSI device */
1523 info = kzalloc(size: sizeof(*info), GFP_KERNEL);
1524 if (info == NULL) { return -ENOMEM; }
1525 info->p_dev = link;
1526 link->priv = info;
1527 data->ScsiInfo = info;
1528
1529 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1530
1531 ret = nsp_cs_config(link);
1532
1533 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1534 return ret;
1535} /* nsp_cs_attach */
1536
1537
1538static void nsp_cs_detach(struct pcmcia_device *link)
1539{
1540 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1541
1542 ((scsi_info_t *)link->priv)->stop = 1;
1543 nsp_cs_release(link);
1544
1545 kfree(objp: link->priv);
1546 link->priv = NULL;
1547} /* nsp_cs_detach */
1548
1549
1550static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1551{
1552 nsp_hw_data *data = priv_data;
1553
1554 if (p_dev->config_index == 0)
1555 return -ENODEV;
1556
1557 /* This reserves IO space but doesn't actually enable it */
1558 if (pcmcia_request_io(p_dev) != 0)
1559 goto next_entry;
1560
1561 if (resource_size(res: p_dev->resource[2])) {
1562 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1563 WIN_MEMORY_TYPE_CM |
1564 WIN_ENABLE);
1565 if (p_dev->resource[2]->end < 0x1000)
1566 p_dev->resource[2]->end = 0x1000;
1567 if (pcmcia_request_window(p_dev, res: p_dev->resource[2], speed: 0) != 0)
1568 goto next_entry;
1569 if (pcmcia_map_mem_page(p_dev, res: p_dev->resource[2],
1570 offset: p_dev->card_addr) != 0)
1571 goto next_entry;
1572
1573 data->MmioAddress = (unsigned long)
1574 ioremap(offset: p_dev->resource[2]->start,
1575 size: resource_size(res: p_dev->resource[2]));
1576 if (!data->MmioAddress)
1577 goto next_entry;
1578
1579 data->MmioLength = resource_size(res: p_dev->resource[2]);
1580 }
1581 /* If we got this far, we're cool! */
1582 return 0;
1583
1584next_entry:
1585 nsp_dbg(NSP_DEBUG_INIT, "next");
1586 pcmcia_disable_device(p_dev);
1587 return -ENODEV;
1588}
1589
1590static int nsp_cs_config(struct pcmcia_device *link)
1591{
1592 int ret;
1593 scsi_info_t *info = link->priv;
1594 struct Scsi_Host *host;
1595 nsp_hw_data *data = &nsp_data_base;
1596
1597 nsp_dbg(NSP_DEBUG_INIT, "in");
1598
1599 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1600 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1601 CONF_AUTO_SET_IO;
1602
1603 ret = pcmcia_loop_config(p_dev: link, conf_check: nsp_cs_config_check, priv_data: data);
1604 if (ret)
1605 goto cs_failed;
1606
1607 if (pcmcia_request_irq(p_dev: link, handler: nspintr))
1608 goto cs_failed;
1609
1610 ret = pcmcia_enable_device(p_dev: link);
1611 if (ret)
1612 goto cs_failed;
1613
1614 if (free_ports) {
1615 if (link->resource[0]) {
1616 release_region(link->resource[0]->start,
1617 resource_size(link->resource[0]));
1618 }
1619 if (link->resource[1]) {
1620 release_region(link->resource[1]->start,
1621 resource_size(link->resource[1]));
1622 }
1623 }
1624
1625 /* Set port and IRQ */
1626 data->BaseAddress = link->resource[0]->start;
1627 data->NumAddress = resource_size(res: link->resource[0]);
1628 data->IrqNumber = link->irq;
1629
1630 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1631 data->BaseAddress, data->NumAddress, data->IrqNumber);
1632
1633 nsphw_init(data);
1634
1635 host = nsp_detect(sht: &nsp_driver_template);
1636
1637 if (host == NULL) {
1638 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1639 goto cs_failed;
1640 }
1641
1642
1643 ret = scsi_add_host (host, NULL);
1644 if (ret)
1645 goto cs_failed;
1646
1647 scsi_scan_host(host);
1648
1649 info->host = host;
1650
1651 return 0;
1652
1653 cs_failed:
1654 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1655 nsp_cs_release(link);
1656
1657 return -ENODEV;
1658} /* nsp_cs_config */
1659
1660
1661static void nsp_cs_release(struct pcmcia_device *link)
1662{
1663 scsi_info_t *info = link->priv;
1664 nsp_hw_data *data = NULL;
1665
1666 if (info->host == NULL) {
1667 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1668 } else {
1669 data = (nsp_hw_data *)info->host->hostdata;
1670 }
1671
1672 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1673
1674 /* Unlink the device chain */
1675 if (info->host != NULL) {
1676 scsi_remove_host(info->host);
1677 }
1678
1679 if (resource_size(res: link->resource[2])) {
1680 if (data != NULL) {
1681 iounmap(addr: (void *)(data->MmioAddress));
1682 }
1683 }
1684 pcmcia_disable_device(p_dev: link);
1685
1686 if (info->host != NULL) {
1687 scsi_host_put(t: info->host);
1688 }
1689} /* nsp_cs_release */
1690
1691static int nsp_cs_suspend(struct pcmcia_device *link)
1692{
1693 scsi_info_t *info = link->priv;
1694 nsp_hw_data *data;
1695
1696 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1697
1698 if (info->host != NULL) {
1699 nsp_msg(KERN_INFO, "clear SDTR status");
1700
1701 data = (nsp_hw_data *)info->host->hostdata;
1702
1703 nsphw_init_sync(data);
1704 }
1705
1706 info->stop = 1;
1707
1708 return 0;
1709}
1710
1711static int nsp_cs_resume(struct pcmcia_device *link)
1712{
1713 scsi_info_t *info = link->priv;
1714 nsp_hw_data *data;
1715
1716 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1717
1718 info->stop = 0;
1719
1720 if (info->host != NULL) {
1721 nsp_msg(KERN_INFO, "reset host and bus");
1722
1723 data = (nsp_hw_data *)info->host->hostdata;
1724
1725 nsphw_init (data);
1726 nsp_bus_reset(data);
1727 }
1728
1729 return 0;
1730}
1731
1732/*======================================================================*
1733 * module entry point
1734 *====================================================================*/
1735static const struct pcmcia_device_id nsp_cs_ids[] = {
1736 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1737 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1738 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1739 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1740 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1741 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1742 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1743 PCMCIA_DEVICE_NULL
1744};
1745MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1746
1747static struct pcmcia_driver nsp_driver = {
1748 .owner = THIS_MODULE,
1749 .name = "nsp_cs",
1750 .probe = nsp_cs_probe,
1751 .remove = nsp_cs_detach,
1752 .id_table = nsp_cs_ids,
1753 .suspend = nsp_cs_suspend,
1754 .resume = nsp_cs_resume,
1755};
1756module_pcmcia_driver(nsp_driver);
1757
1758/* end */
1759

source code of linux/drivers/scsi/pcmcia/nsp_cs.c