blob: e40a8c22aa9d84f7bcd9d761f964f7221cc4e20d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*======================================================================
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/* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */
29
30#include <linux/version.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34#include <linux/sched.h>
35#include <linux/slab.h>
36#include <linux/string.h>
37#include <linux/timer.h>
38#include <linux/ioport.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h>
41#include <linux/major.h>
42#include <linux/blkdev.h>
43#include <linux/stat.h>
44
45#include <asm/io.h>
46#include <asm/irq.h>
47
48#include <../drivers/scsi/scsi.h>
49#include <scsi/scsi_host.h>
50
51#include <scsi/scsi.h>
52#include <scsi/scsi_ioctl.h>
53
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <pcmcia/cs_types.h>
55#include <pcmcia/cs.h>
56#include <pcmcia/cistpl.h>
57#include <pcmcia/cisreg.h>
58#include <pcmcia/ds.h>
59
60#include "nsp_cs.h"
61
62MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
63MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
64MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
65#ifdef MODULE_LICENSE
66MODULE_LICENSE("GPL");
67#endif
68
69#include "nsp_io.h"
70
71/*====================================================================*/
72/* Parameters that can be set with 'insmod' */
73
74static int nsp_burst_mode = BURST_MEM32;
75module_param(nsp_burst_mode, int, 0);
76MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
77
78/* Release IO ports after configuration? */
79static int free_ports = 0;
80module_param(free_ports, bool, 0);
81MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
82
83/* /usr/src/linux/drivers/scsi/hosts.h */
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +010084static struct scsi_host_template nsp_driver_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 .proc_name = "nsp_cs",
86 .proc_info = nsp_proc_info,
87 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
88#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
89 .detect = nsp_detect_old,
90 .release = nsp_release_old,
91#endif
92 .info = nsp_info,
93 .queuecommand = nsp_queuecommand,
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* .eh_abort_handler = nsp_eh_abort,*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 .eh_bus_reset_handler = nsp_eh_bus_reset,
96 .eh_host_reset_handler = nsp_eh_host_reset,
97 .can_queue = 1,
98 .this_id = NSP_INITIATOR_ID,
99 .sg_tablesize = SG_ALL,
100 .cmd_per_lun = 1,
101 .use_clustering = DISABLE_CLUSTERING,
102#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
103 .use_new_eh_code = 1,
104#endif
105};
106
107static dev_link_t *dev_list = NULL;
108static dev_info_t dev_info = {"nsp_cs"};
109
110static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
111
112
113
114/*
115 * debug, error print
116 */
117#ifndef NSP_DEBUG
118# define NSP_DEBUG_MASK 0x000000
119# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
120# define nsp_dbg(mask, args...) /* */
121#else
122# define NSP_DEBUG_MASK 0xffffff
123# define nsp_msg(type, args...) \
124 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
125# define nsp_dbg(mask, args...) \
126 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
127#endif
128
129#define NSP_DEBUG_QUEUECOMMAND BIT(0)
130#define NSP_DEBUG_REGISTER BIT(1)
131#define NSP_DEBUG_AUTOSCSI BIT(2)
132#define NSP_DEBUG_INTR BIT(3)
133#define NSP_DEBUG_SGLIST BIT(4)
134#define NSP_DEBUG_BUSFREE BIT(5)
135#define NSP_DEBUG_CDB_CONTENTS BIT(6)
136#define NSP_DEBUG_RESELECTION BIT(7)
137#define NSP_DEBUG_MSGINOCCUR BIT(8)
138#define NSP_DEBUG_EEPROM BIT(9)
139#define NSP_DEBUG_MSGOUTOCCUR BIT(10)
140#define NSP_DEBUG_BUSRESET BIT(11)
141#define NSP_DEBUG_RESTART BIT(12)
142#define NSP_DEBUG_SYNC BIT(13)
143#define NSP_DEBUG_WAIT BIT(14)
144#define NSP_DEBUG_TARGETFLAG BIT(15)
145#define NSP_DEBUG_PROC BIT(16)
146#define NSP_DEBUG_INIT BIT(17)
147#define NSP_DEBUG_DATA_IO BIT(18)
148#define NSP_SPECIAL_PRINT_REGISTER BIT(20)
149
150#define NSP_DEBUG_BUF_LEN 150
151
152static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
153{
154 va_list args;
155 char buf[NSP_DEBUG_BUF_LEN];
156
157 va_start(args, fmt);
158 vsnprintf(buf, sizeof(buf), fmt, args);
159 va_end(args);
160
161#ifndef NSP_DEBUG
162 printk("%snsp_cs: %s\n", type, buf);
163#else
164 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
165#endif
166}
167
168#ifdef NSP_DEBUG
169static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
170{
171 va_list args;
172 char buf[NSP_DEBUG_BUF_LEN];
173
174 va_start(args, fmt);
175 vsnprintf(buf, sizeof(buf), fmt, args);
176 va_end(args);
177
178 if (mask & NSP_DEBUG_MASK) {
179 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
180 }
181}
182#endif
183
184/***********************************************************/
185
186/*====================================================
187 * Clenaup parameters and call done() functions.
188 * You must be set SCpnt->result before call this function.
189 */
190static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
191{
192 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
193
194 data->CurrentSC = NULL;
195
196 SCpnt->scsi_done(SCpnt);
197}
198
199static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
200{
201#ifdef NSP_DEBUG
202 /*unsigned int host_id = SCpnt->device->host->this_id;*/
203 /*unsigned int base = SCpnt->device->host->io_port;*/
Jeff Garzik422c0d62005-10-24 18:05:09 -0400204 unsigned char target = scmd_id(SCpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205#endif
206 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
207
208 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
209 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
210 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
211
212 SCpnt->scsi_done = done;
213
214 if (data->CurrentSC != NULL) {
215 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
216 SCpnt->result = DID_BAD_TARGET << 16;
217 nsp_scsi_done(SCpnt);
218 return 0;
219 }
220
221#if 0
222 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
223 This makes kernel crash when suspending... */
224 if (data->ScsiInfo->stop != 0) {
225 nsp_msg(KERN_INFO, "suspending device. reject command.");
226 SCpnt->result = DID_BAD_TARGET << 16;
227 nsp_scsi_done(SCpnt);
228 return SCSI_MLQUEUE_HOST_BUSY;
229 }
230#endif
231
232 show_command(SCpnt);
233
234 data->CurrentSC = SCpnt;
235
236 SCpnt->SCp.Status = CHECK_CONDITION;
237 SCpnt->SCp.Message = 0;
238 SCpnt->SCp.have_data_in = IO_UNKNOWN;
239 SCpnt->SCp.sent_command = 0;
240 SCpnt->SCp.phase = PH_UNDETERMINED;
241 SCpnt->resid = SCpnt->request_bufflen;
242
243 /* setup scratch area
244 SCp.ptr : buffer pointer
245 SCp.this_residual : buffer length
246 SCp.buffer : next buffer
247 SCp.buffers_residual : left buffers in list
248 SCp.phase : current state of the command */
249 if (SCpnt->use_sg) {
250 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
251 SCpnt->SCp.ptr = BUFFER_ADDR;
252 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
253 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
254 } else {
255 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
256 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
257 SCpnt->SCp.buffer = NULL;
258 SCpnt->SCp.buffers_residual = 0;
259 }
260
261 if (nsphw_start_selection(SCpnt) == FALSE) {
262 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
263 SCpnt->result = DID_BUS_BUSY << 16;
264 nsp_scsi_done(SCpnt);
265 return 0;
266 }
267
268
269 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
270#ifdef NSP_DEBUG
271 data->CmdId++;
272#endif
273 return 0;
274}
275
276/*
277 * setup PIO FIFO transfer mode and enable/disable to data out
278 */
279static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
280{
281 unsigned int base = data->BaseAddress;
282 unsigned char transfer_mode_reg;
283
284 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
285
286 if (enabled != FALSE) {
287 transfer_mode_reg = TRANSFER_GO | BRAIND;
288 } else {
289 transfer_mode_reg = 0;
290 }
291
292 transfer_mode_reg |= data->TransferMode;
293
294 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
295}
296
297static void nsphw_init_sync(nsp_hw_data *data)
298{
299 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
300 .SyncPeriod = 0,
301 .SyncOffset = 0
302 };
303 int i;
304
305 /* setup sync data */
306 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
307 data->Sync[i] = tmp_sync;
308 }
309}
310
311/*
312 * Initialize Ninja hardware
313 */
314static int nsphw_init(nsp_hw_data *data)
315{
316 unsigned int base = data->BaseAddress;
317
318 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
319
320 data->ScsiClockDiv = CLOCK_40M | FAST_20;
321 data->CurrentSC = NULL;
322 data->FifoCount = 0;
323 data->TransferMode = MODE_IO8;
324
325 nsphw_init_sync(data);
326
327 /* block all interrupts */
328 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
329
330 /* setup SCSI interface */
331 nsp_write(base, IFSELECT, IF_IFSEL);
332
333 nsp_index_write(base, SCSIIRQMODE, 0);
334
335 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
336 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
337
338 nsp_index_write(base, PARITYCTRL, 0);
339 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
340 ACK_COUNTER_CLEAR |
341 REQ_COUNTER_CLEAR |
342 HOST_COUNTER_CLEAR);
343
344 /* setup fifo asic */
345 nsp_write(base, IFSELECT, IF_REGSEL);
346 nsp_index_write(base, TERMPWRCTRL, 0);
347 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
348 nsp_msg(KERN_INFO, "terminator power on");
349 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
350 }
351
352 nsp_index_write(base, TIMERCOUNT, 0);
353 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
354
355 nsp_index_write(base, SYNCREG, 0);
356 nsp_index_write(base, ACKWIDTH, 0);
357
358 /* enable interrupts and ack them */
359 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
360 RESELECT_EI |
361 SCSI_RESET_IRQ_EI );
362 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
363
364 nsp_setup_fifo(data, FALSE);
365
366 return TRUE;
367}
368
369/*
370 * Start selection phase
371 */
372static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
373{
374 unsigned int host_id = SCpnt->device->host->this_id;
375 unsigned int base = SCpnt->device->host->io_port;
Jeff Garzik422c0d62005-10-24 18:05:09 -0400376 unsigned char target = scmd_id(SCpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
378 int time_out;
379 unsigned char phase, arbit;
380
381 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
382
383 phase = nsp_index_read(base, SCSIBUSMON);
384 if(phase != BUSMON_BUS_FREE) {
385 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
386 return FALSE;
387 }
388
389 /* start arbitration */
390 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
391 SCpnt->SCp.phase = PH_ARBSTART;
392 nsp_index_write(base, SETARBIT, ARBIT_GO);
393
394 time_out = 1000;
395 do {
396 /* XXX: what a stupid chip! */
397 arbit = nsp_index_read(base, ARBITSTATUS);
398 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
399 udelay(1); /* hold 1.2us */
400 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
401 (time_out-- != 0));
402
403 if (!(arbit & ARBIT_WIN)) {
404 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
405 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
406 return FALSE;
407 }
408
409 /* assert select line */
410 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
411 SCpnt->SCp.phase = PH_SELSTART;
412 udelay(3); /* wait 2.4us */
413 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
414 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
415 udelay(2); /* wait >1.2us */
416 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
417 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
418 /*udelay(1);*/ /* wait >90ns */
419 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
420
421 /* check selection timeout */
422 nsp_start_timer(SCpnt, 1000/51);
423 data->SelectionTimeOut = 1;
424
425 return TRUE;
426}
427
428struct nsp_sync_table {
429 unsigned int min_period;
430 unsigned int max_period;
431 unsigned int chip_period;
432 unsigned int ack_width;
433};
434
435static struct nsp_sync_table nsp_sync_table_40M[] = {
436 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
437 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
438 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
439 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
440 { 0, 0, 0, 0},
441};
442
443static struct nsp_sync_table nsp_sync_table_20M[] = {
444 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
445 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
446 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
447 { 0, 0, 0, 0},
448};
449
450/*
451 * setup synchronous data transfer mode
452 */
453static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
454{
Jeff Garzik422c0d62005-10-24 18:05:09 -0400455 unsigned char target = scmd_id(SCpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456// unsigned char lun = SCpnt->device->lun;
457 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
458 sync_data *sync = &(data->Sync[target]);
459 struct nsp_sync_table *sync_table;
460 unsigned int period, offset;
461 int i;
462
463
464 nsp_dbg(NSP_DEBUG_SYNC, "in");
465
466 period = sync->SyncPeriod;
467 offset = sync->SyncOffset;
468
469 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
470
471 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
472 sync_table = nsp_sync_table_20M;
473 } else {
474 sync_table = nsp_sync_table_40M;
475 }
476
477 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
478 if ( period >= sync_table->min_period &&
479 period <= sync_table->max_period ) {
480 break;
481 }
482 }
483
484 if (period != 0 && sync_table->max_period == 0) {
485 /*
486 * No proper period/offset found
487 */
488 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
489
490 sync->SyncPeriod = 0;
491 sync->SyncOffset = 0;
492 sync->SyncRegister = 0;
493 sync->AckWidth = 0;
494
495 return FALSE;
496 }
497
498 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
499 (offset & SYNCREG_OFFSET_MASK);
500 sync->AckWidth = sync_table->ack_width;
501
502 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
503
504 return TRUE;
505}
506
507
508/*
509 * start ninja hardware timer
510 */
511static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
512{
513 unsigned int base = SCpnt->device->host->io_port;
514 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
515
516 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
517 data->TimerCount = time;
518 nsp_index_write(base, TIMERCOUNT, time);
519}
520
521/*
522 * wait for bus phase change
523 */
524static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
525{
526 unsigned int base = SCpnt->device->host->io_port;
527 unsigned char reg;
528 int time_out;
529
530 //nsp_dbg(NSP_DEBUG_INTR, "in");
531
532 time_out = 100;
533
534 do {
535 reg = nsp_index_read(base, SCSIBUSMON);
536 if (reg == 0xff) {
537 break;
538 }
539 } while ((time_out-- != 0) && (reg & mask) != 0);
540
541 if (time_out == 0) {
542 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
543 }
544
545 return 0;
546}
547
548/*
549 * expect Ninja Irq
550 */
551static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
552 unsigned char current_phase,
553 unsigned char mask)
554{
555 unsigned int base = SCpnt->device->host->io_port;
556 int time_out;
557 unsigned char phase, i_src;
558
559 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
560
561 time_out = 100;
562 do {
563 phase = nsp_index_read(base, SCSIBUSMON);
564 if (phase == 0xff) {
565 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
566 return -1;
567 }
568 i_src = nsp_read(base, IRQSTATUS);
569 if (i_src & IRQSTATUS_SCSI) {
570 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
571 return 0;
572 }
573 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
574 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
575 return 1;
576 }
577 } while(time_out-- != 0);
578
579 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
580 return -1;
581}
582
583/*
584 * transfer SCSI message
585 */
586static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
587{
588 unsigned int base = SCpnt->device->host->io_port;
589 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
590 char *buf = data->MsgBuffer;
591 int len = min(MSGBUF_SIZE, data->MsgLen);
592 int ptr;
593 int ret;
594
595 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
596 for (ptr = 0; len > 0; len--, ptr++) {
597
598 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
599 if (ret <= 0) {
600 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
601 return 0;
602 }
603
604 /* if last byte, negate ATN */
605 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
606 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
607 }
608
609 /* read & write message */
610 if (phase & BUSMON_IO) {
611 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
612 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
613 } else {
614 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
615 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
616 }
617 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
618
619 }
620 return len;
621}
622
623/*
624 * get extra SCSI data from fifo
625 */
626static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
627{
628 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
629 unsigned int count;
630
631 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
632
633 if (SCpnt->SCp.have_data_in != IO_IN) {
634 return 0;
635 }
636
637 count = nsp_fifo_count(SCpnt);
638 if (data->FifoCount == count) {
639 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
640 return 0;
641 }
642
643 /*
644 * XXX: NSP_QUIRK
645 * data phase skip only occures in case of SCSI_LOW_READ
646 */
647 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
648 SCpnt->SCp.phase = PH_DATA;
649 nsp_pio_read(SCpnt);
650 nsp_setup_fifo(data, FALSE);
651
652 return 0;
653}
654
655/*
656 * accept reselection
657 */
658static int nsp_reselected(Scsi_Cmnd *SCpnt)
659{
660 unsigned int base = SCpnt->device->host->io_port;
661 unsigned int host_id = SCpnt->device->host->this_id;
662 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
663 unsigned char bus_reg;
664 unsigned char id_reg, tmp;
665 int target;
666
667 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
668
669 id_reg = nsp_index_read(base, RESELECTID);
670 tmp = id_reg & (~BIT(host_id));
671 target = 0;
672 while(tmp != 0) {
673 if (tmp & BIT(0)) {
674 break;
675 }
676 tmp >>= 1;
677 target++;
678 }
679
Jeff Garzik422c0d62005-10-24 18:05:09 -0400680 if (scmd_id(SCpnt) != target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
682 }
683
684 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
685
686 nsp_nexus(SCpnt);
687 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
688 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
689 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
690
691 return TRUE;
692}
693
694/*
695 * count how many data transferd
696 */
697static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
698{
699 unsigned int base = SCpnt->device->host->io_port;
700 unsigned int count;
701 unsigned int l, m, h, dummy;
702
703 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
704
705 l = nsp_index_read(base, TRANSFERCOUNT);
706 m = nsp_index_read(base, TRANSFERCOUNT);
707 h = nsp_index_read(base, TRANSFERCOUNT);
708 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
709
710 count = (h << 16) | (m << 8) | (l << 0);
711
712 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
713
714 return count;
715}
716
717/* fifo size */
718#define RFIFO_CRIT 64
719#define WFIFO_CRIT 64
720
721/*
722 * read data in DATA IN phase
723 */
724static void nsp_pio_read(Scsi_Cmnd *SCpnt)
725{
726 unsigned int base = SCpnt->device->host->io_port;
727 unsigned long mmio_base = SCpnt->device->host->base;
728 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
729 long time_out;
730 int ocount, res;
731 unsigned char stat, fifo_stat;
732
733 ocount = data->FifoCount;
734
735 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",
736 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
737
738 time_out = 1000;
739
740 while ((time_out-- != 0) &&
741 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
742
743 stat = nsp_index_read(base, SCSIBUSMON);
744 stat &= BUSMON_PHASE_MASK;
745
746
747 res = nsp_fifo_count(SCpnt) - ocount;
748 //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);
749 if (res == 0) { /* if some data avilable ? */
750 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
751 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
752 continue;
753 } else {
754 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
755 break;
756 }
757 }
758
759 fifo_stat = nsp_read(base, FIFOSTATUS);
760 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
761 stat == BUSPHASE_DATA_IN) {
762 continue;
763 }
764
765 res = min(res, SCpnt->SCp.this_residual);
766
767 switch (data->TransferMode) {
768 case MODE_IO32:
769 res &= ~(BIT(1)|BIT(0)); /* align 4 */
770 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
771 break;
772 case MODE_IO8:
773 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
774 break;
775
776 case MODE_MEM32:
777 res &= ~(BIT(1)|BIT(0)); /* align 4 */
778 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
779 break;
780
781 default:
782 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
783 return;
784 }
785
786 SCpnt->resid -= res;
787 SCpnt->SCp.ptr += res;
788 SCpnt->SCp.this_residual -= res;
789 ocount += res;
790 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
791
792 /* go to next scatter list if available */
793 if (SCpnt->SCp.this_residual == 0 &&
794 SCpnt->SCp.buffers_residual != 0 ) {
795 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
796 SCpnt->SCp.buffers_residual--;
797 SCpnt->SCp.buffer++;
798 SCpnt->SCp.ptr = BUFFER_ADDR;
799 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
800 time_out = 1000;
801
802 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
803 }
804 }
805
806 data->FifoCount = ocount;
807
808 if (time_out == 0) {
809 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
810 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
811 }
812 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
813 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
814}
815
816/*
817 * write data in DATA OUT phase
818 */
819static void nsp_pio_write(Scsi_Cmnd *SCpnt)
820{
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, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
832
833 time_out = 1000;
834
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;
839
840 if (stat != BUSPHASE_DATA_OUT) {
841 res = ocount - nsp_fifo_count(SCpnt);
842
843 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
844 /* Put back pointer */
845 SCpnt->resid += res;
846 SCpnt->SCp.ptr -= res;
847 SCpnt->SCp.this_residual += res;
848 ocount -= res;
849
850 break;
851 }
852
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;
857 }
858
859 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
860
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;
870
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;
875
876 default:
877 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
878 break;
879 }
880
881 SCpnt->resid -= res;
882 SCpnt->SCp.ptr += res;
883 SCpnt->SCp.this_residual -= res;
884 ocount += res;
885
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;
895 }
896 }
897
898 data->FifoCount = ocount;
899
900 if (time_out == 0) {
901 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
902 }
903 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
904 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
905}
906#undef RFIFO_CRIT
907#undef WFIFO_CRIT
908
909/*
910 * setup synchronous/asynchronous data transfer mode
911 */
912static int nsp_nexus(Scsi_Cmnd *SCpnt)
913{
914 unsigned int base = SCpnt->device->host->io_port;
Jeff Garzik422c0d62005-10-24 18:05:09 -0400915 unsigned char target = scmd_id(SCpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916// unsigned char lun = SCpnt->device->lun;
917 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
918 sync_data *sync = &(data->Sync[target]);
919
920 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
921
922 /* setup synch transfer registers */
923 nsp_index_write(base, SYNCREG, sync->SyncRegister);
924 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
925
926 if (SCpnt->use_sg == 0 ||
927 SCpnt->resid % 4 != 0 ||
928 SCpnt->resid <= PAGE_SIZE ) {
929 data->TransferMode = MODE_IO8;
930 } else if (nsp_burst_mode == BURST_MEM32) {
931 data->TransferMode = MODE_MEM32;
932 } else if (nsp_burst_mode == BURST_IO32) {
933 data->TransferMode = MODE_IO32;
934 } else {
935 data->TransferMode = MODE_IO8;
936 }
937
938 /* setup pdma fifo */
939 nsp_setup_fifo(data, TRUE);
940
941 /* clear ack counter */
942 data->FifoCount = 0;
943 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
944 ACK_COUNTER_CLEAR |
945 REQ_COUNTER_CLEAR |
946 HOST_COUNTER_CLEAR);
947
948 return 0;
949}
950
951#include "nsp_message.c"
952/*
953 * interrupt handler
954 */
955static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
956{
957 unsigned int base;
958 unsigned char irq_status, irq_phase, phase;
959 Scsi_Cmnd *tmpSC;
960 unsigned char target, lun;
961 unsigned int *sync_neg;
962 int i, tmp;
963 nsp_hw_data *data;
964
965
966 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
967 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
968
969 if ( dev_id != NULL &&
970 ((scsi_info_t *)dev_id)->host != NULL ) {
971 scsi_info_t *info = (scsi_info_t *)dev_id;
972
973 data = (nsp_hw_data *)info->host->hostdata;
974 } else {
975 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
976 return IRQ_NONE;
977 }
978
979 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
980
981 base = data->BaseAddress;
982 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
983
984 /*
985 * interrupt check
986 */
987 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
988 irq_status = nsp_read(base, IRQSTATUS);
989 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
990 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
991 nsp_write(base, IRQCONTROL, 0);
992 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
993 return IRQ_NONE;
994 }
995
996 /* XXX: IMPORTANT
997 * Do not read an irq_phase register if no scsi phase interrupt.
998 * Unless, you should lose a scsi phase interrupt.
999 */
1000 phase = nsp_index_read(base, SCSIBUSMON);
1001 if((irq_status & IRQSTATUS_SCSI) != 0) {
1002 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1003 } else {
1004 irq_phase = 0;
1005 }
1006
1007 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1008
1009 /*
1010 * timer interrupt handler (scsi vs timer interrupts)
1011 */
1012 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1013 if (data->TimerCount != 0) {
1014 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1015 nsp_index_write(base, TIMERCOUNT, 0);
1016 nsp_index_write(base, TIMERCOUNT, 0);
1017 data->TimerCount = 0;
1018 }
1019
1020 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1021 data->SelectionTimeOut == 0) {
1022 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1023 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1024 return IRQ_HANDLED;
1025 }
1026
1027 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1028
1029 if ((irq_status & IRQSTATUS_SCSI) &&
1030 (irq_phase & SCSI_RESET_IRQ)) {
1031 nsp_msg(KERN_ERR, "bus reset (power off?)");
1032
1033 nsphw_init(data);
1034 nsp_bus_reset(data);
1035
1036 if(data->CurrentSC != NULL) {
1037 tmpSC = data->CurrentSC;
1038 tmpSC->result = (DID_RESET << 16) |
1039 ((tmpSC->SCp.Message & 0xff) << 8) |
1040 ((tmpSC->SCp.Status & 0xff) << 0);
1041 nsp_scsi_done(tmpSC);
1042 }
1043 return IRQ_HANDLED;
1044 }
1045
1046 if (data->CurrentSC == NULL) {
1047 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);
1048 nsphw_init(data);
1049 nsp_bus_reset(data);
1050 return IRQ_HANDLED;
1051 }
1052
1053 tmpSC = data->CurrentSC;
1054 target = tmpSC->device->id;
1055 lun = tmpSC->device->lun;
1056 sync_neg = &(data->Sync[target].SyncNegotiation);
1057
1058 /*
1059 * parse hardware SCSI irq reasons register
1060 */
1061 if (irq_status & IRQSTATUS_SCSI) {
1062 if (irq_phase & RESELECT_IRQ) {
1063 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1064 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1065 if (nsp_reselected(tmpSC) != FALSE) {
1066 return IRQ_HANDLED;
1067 }
1068 }
1069
1070 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1071 return IRQ_HANDLED;
1072 }
1073 }
1074
1075 //show_phase(tmpSC);
1076
1077 switch(tmpSC->SCp.phase) {
1078 case PH_SELSTART:
1079 // *sync_neg = SYNC_NOT_YET;
1080 if ((phase & BUSMON_BSY) == 0) {
1081 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1082 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1083 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1084 data->SelectionTimeOut = 0;
1085 nsp_index_write(base, SCSIBUSCTRL, 0);
1086
1087 tmpSC->result = DID_TIME_OUT << 16;
1088 nsp_scsi_done(tmpSC);
1089
1090 return IRQ_HANDLED;
1091 }
1092 data->SelectionTimeOut += 1;
1093 nsp_start_timer(tmpSC, 1000/51);
1094 return IRQ_HANDLED;
1095 }
1096
1097 /* attention assert */
1098 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1099 data->SelectionTimeOut = 0;
1100 tmpSC->SCp.phase = PH_SELECTED;
1101 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1102 udelay(1);
1103 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1104 return IRQ_HANDLED;
1105
1106 break;
1107
1108 case PH_RESELECT:
1109 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1110 // *sync_neg = SYNC_NOT_YET;
1111 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1112
1113 tmpSC->result = DID_ABORT << 16;
1114 nsp_scsi_done(tmpSC);
1115 return IRQ_HANDLED;
1116 }
1117 /* fall thru */
1118 default:
1119 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1120 return IRQ_HANDLED;
1121 }
1122 break;
1123 }
1124
1125 /*
1126 * SCSI sequencer
1127 */
1128 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1129
1130 /* normal disconnect */
1131 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1132 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1133 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1134
1135 //*sync_neg = SYNC_NOT_YET;
1136
1137 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1138 tmpSC->result = (DID_OK << 16) |
1139 ((tmpSC->SCp.Message & 0xff) << 8) |
1140 ((tmpSC->SCp.Status & 0xff) << 0);
1141 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1142 nsp_scsi_done(tmpSC);
1143
1144 return IRQ_HANDLED;
1145 }
1146
1147 return IRQ_HANDLED;
1148 }
1149
1150
1151 /* check unexpected bus free state */
1152 if (phase == 0) {
1153 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1154
1155 *sync_neg = SYNC_NG;
1156 tmpSC->result = DID_ERROR << 16;
1157 nsp_scsi_done(tmpSC);
1158 return IRQ_HANDLED;
1159 }
1160
1161 switch (phase & BUSMON_PHASE_MASK) {
1162 case BUSPHASE_COMMAND:
1163 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1164 if ((phase & BUSMON_REQ) == 0) {
1165 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1166 return IRQ_HANDLED;
1167 }
1168
1169 tmpSC->SCp.phase = PH_COMMAND;
1170
1171 nsp_nexus(tmpSC);
1172
1173 /* write scsi command */
1174 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1175 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1176 for (i = 0; i < tmpSC->cmd_len; i++) {
1177 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1178 }
1179 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1180 break;
1181
1182 case BUSPHASE_DATA_OUT:
1183 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1184
1185 tmpSC->SCp.phase = PH_DATA;
1186 tmpSC->SCp.have_data_in = IO_OUT;
1187
1188 nsp_pio_write(tmpSC);
1189
1190 break;
1191
1192 case BUSPHASE_DATA_IN:
1193 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1194
1195 tmpSC->SCp.phase = PH_DATA;
1196 tmpSC->SCp.have_data_in = IO_IN;
1197
1198 nsp_pio_read(tmpSC);
1199
1200 break;
1201
1202 case BUSPHASE_STATUS:
1203 nsp_dataphase_bypass(tmpSC);
1204 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1205
1206 tmpSC->SCp.phase = PH_STATUS;
1207
1208 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1209 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1210
1211 break;
1212
1213 case BUSPHASE_MESSAGE_OUT:
1214 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1215 if ((phase & BUSMON_REQ) == 0) {
1216 goto timer_out;
1217 }
1218
1219 tmpSC->SCp.phase = PH_MSG_OUT;
1220
1221 //*sync_neg = SYNC_NOT_YET;
1222
1223 data->MsgLen = i = 0;
1224 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1225
1226 if (*sync_neg == SYNC_NOT_YET) {
1227 data->Sync[target].SyncPeriod = 0;
1228 data->Sync[target].SyncOffset = 0;
1229
1230 /**/
1231 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1232 data->MsgBuffer[i] = 3; i++;
1233 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1234 data->MsgBuffer[i] = 0x0c; i++;
1235 data->MsgBuffer[i] = 15; i++;
1236 /**/
1237 }
1238 data->MsgLen = i;
1239
1240 nsp_analyze_sdtr(tmpSC);
1241 show_message(data);
1242 nsp_message_out(tmpSC);
1243 break;
1244
1245 case BUSPHASE_MESSAGE_IN:
1246 nsp_dataphase_bypass(tmpSC);
1247 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1248 if ((phase & BUSMON_REQ) == 0) {
1249 goto timer_out;
1250 }
1251
1252 tmpSC->SCp.phase = PH_MSG_IN;
1253 nsp_message_in(tmpSC);
1254
1255 /**/
1256 if (*sync_neg == SYNC_NOT_YET) {
1257 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1258
1259 if (data->MsgLen >= 5 &&
1260 data->MsgBuffer[0] == MSG_EXTENDED &&
1261 data->MsgBuffer[1] == 3 &&
1262 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1263 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1264 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1265 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1266 *sync_neg = SYNC_OK;
1267 } else {
1268 data->Sync[target].SyncPeriod = 0;
1269 data->Sync[target].SyncOffset = 0;
1270 *sync_neg = SYNC_NG;
1271 }
1272 nsp_analyze_sdtr(tmpSC);
1273 }
1274 /**/
1275
1276 /* search last messeage byte */
1277 tmp = -1;
1278 for (i = 0; i < data->MsgLen; i++) {
1279 tmp = data->MsgBuffer[i];
1280 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1281 i += (1 + data->MsgBuffer[i+1]);
1282 }
1283 }
1284 tmpSC->SCp.Message = tmp;
1285
1286 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1287 show_message(data);
1288
1289 break;
1290
1291 case BUSPHASE_SELECT:
1292 default:
1293 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1294
1295 break;
1296 }
1297
1298 //nsp_dbg(NSP_DEBUG_INTR, "out");
1299 return IRQ_HANDLED;
1300
1301timer_out:
1302 nsp_start_timer(tmpSC, 1000/102);
1303 return IRQ_HANDLED;
1304}
1305
1306#ifdef NSP_DEBUG
1307#include "nsp_debug.c"
1308#endif /* NSP_DEBUG */
1309
1310/*----------------------------------------------------------------*/
1311/* look for ninja3 card and init if found */
1312/*----------------------------------------------------------------*/
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +01001313static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314{
1315 struct Scsi_Host *host; /* registered host structure */
1316 nsp_hw_data *data_b = &nsp_data_base, *data;
1317
1318 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1319#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1320 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1321#else
1322 host = scsi_register(sht, sizeof(nsp_hw_data));
1323#endif
1324 if (host == NULL) {
1325 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1326 return NULL;
1327 }
1328
1329 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1330 data = (nsp_hw_data *)host->hostdata;
1331 data->ScsiInfo->host = host;
1332#ifdef NSP_DEBUG
1333 data->CmdId = 0;
1334#endif
1335
1336 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1337
1338 host->unique_id = data->BaseAddress;
1339 host->io_port = data->BaseAddress;
1340 host->n_io_port = data->NumAddress;
1341 host->irq = data->IrqNumber;
1342 host->base = data->MmioAddress;
1343
1344 spin_lock_init(&(data->Lock));
1345
1346 snprintf(data->nspinfo,
1347 sizeof(data->nspinfo),
1348 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1349 host->io_port, host->io_port + host->n_io_port - 1,
1350 host->base,
1351 host->irq);
1352 sht->name = data->nspinfo;
1353
1354 nsp_dbg(NSP_DEBUG_INIT, "end");
1355
1356
1357 return host; /* detect done. */
1358}
1359
1360#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +01001361static int nsp_detect_old(struct scsi_host_template *sht)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362{
1363 if (nsp_detect(sht) == NULL) {
1364 return 0;
1365 } else {
1366 //MOD_INC_USE_COUNT;
1367 return 1;
1368 }
1369}
1370
1371
1372static int nsp_release_old(struct Scsi_Host *shpnt)
1373{
1374 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1375
1376 /* PCMCIA Card Service dose same things below. */
1377 /* So we do nothing. */
1378 //if (shpnt->irq) {
1379 // free_irq(shpnt->irq, data->ScsiInfo);
1380 //}
1381 //if (shpnt->io_port) {
1382 // release_region(shpnt->io_port, shpnt->n_io_port);
1383 //}
1384
1385 //MOD_DEC_USE_COUNT;
1386
1387 return 0;
1388}
1389#endif
1390
1391/*----------------------------------------------------------------*/
1392/* return info string */
1393/*----------------------------------------------------------------*/
1394static const char *nsp_info(struct Scsi_Host *shpnt)
1395{
1396 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1397
1398 return data->nspinfo;
1399}
1400
1401#undef SPRINTF
1402#define SPRINTF(args...) \
1403 do { \
1404 if(length > (pos - buffer)) { \
1405 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1406 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1407 } \
1408 } while(0)
1409static int
1410nsp_proc_info(
1411#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1412 struct Scsi_Host *host,
1413#endif
1414 char *buffer,
1415 char **start,
1416 off_t offset,
1417 int length,
1418#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1419 int hostno,
1420#endif
1421 int inout)
1422{
1423 int id;
1424 char *pos = buffer;
1425 int thislength;
1426 int speed;
1427 unsigned long flags;
1428 nsp_hw_data *data;
1429#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1430 struct Scsi_Host *host;
1431#else
1432 int hostno;
1433#endif
1434 if (inout) {
1435 return -EINVAL;
1436 }
1437
1438#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1439 hostno = host->host_no;
1440#else
1441 /* search this HBA host */
1442 host = scsi_host_hn_get(hostno);
1443 if (host == NULL) {
1444 return -ESRCH;
1445 }
1446#endif
1447 data = (nsp_hw_data *)host->hostdata;
1448
1449
1450 SPRINTF("NinjaSCSI status\n\n");
1451 SPRINTF("Driver version: $Revision: 1.23 $\n");
1452 SPRINTF("SCSI host No.: %d\n", hostno);
1453 SPRINTF("IRQ: %d\n", host->irq);
1454 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1455 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1456 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1457
1458 SPRINTF("burst transfer mode: ");
1459 switch (nsp_burst_mode) {
1460 case BURST_IO8:
1461 SPRINTF("io8");
1462 break;
1463 case BURST_IO32:
1464 SPRINTF("io32");
1465 break;
1466 case BURST_MEM32:
1467 SPRINTF("mem32");
1468 break;
1469 default:
1470 SPRINTF("???");
1471 break;
1472 }
1473 SPRINTF("\n");
1474
1475
1476 spin_lock_irqsave(&(data->Lock), flags);
1477 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1478 spin_unlock_irqrestore(&(data->Lock), flags);
1479
1480 SPRINTF("SDTR status\n");
1481 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1482
1483 SPRINTF("id %d: ", id);
1484
1485 if (id == host->this_id) {
1486 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1487 continue;
1488 }
1489
1490 switch(data->Sync[id].SyncNegotiation) {
1491 case SYNC_OK:
1492 SPRINTF(" sync");
1493 break;
1494 case SYNC_NG:
1495 SPRINTF("async");
1496 break;
1497 case SYNC_NOT_YET:
1498 SPRINTF(" none");
1499 break;
1500 default:
1501 SPRINTF("?????");
1502 break;
1503 }
1504
1505 if (data->Sync[id].SyncPeriod != 0) {
1506 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1507
1508 SPRINTF(" transfer %d.%dMB/s, offset %d",
1509 speed / 1000,
1510 speed % 1000,
1511 data->Sync[id].SyncOffset
1512 );
1513 }
1514 SPRINTF("\n");
1515 }
1516
1517 thislength = pos - (buffer + offset);
1518
1519 if(thislength < 0) {
1520 *start = NULL;
1521 return 0;
1522 }
1523
1524
1525 thislength = min(thislength, length);
1526 *start = buffer + offset;
1527
1528 return thislength;
1529}
1530#undef SPRINTF
1531
1532/*---------------------------------------------------------------*/
1533/* error handler */
1534/*---------------------------------------------------------------*/
1535
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536/*
1537static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1538{
1539 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1540
1541 return nsp_eh_bus_reset(SCpnt);
1542}*/
1543
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544static int nsp_bus_reset(nsp_hw_data *data)
1545{
1546 unsigned int base = data->BaseAddress;
1547 int i;
1548
1549 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1550
1551 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1552 mdelay(100); /* 100ms */
1553 nsp_index_write(base, SCSIBUSCTRL, 0);
1554 for(i = 0; i < 5; i++) {
1555 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1556 }
1557
1558 nsphw_init_sync(data);
1559
1560 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1561
1562 return SUCCESS;
1563}
1564
1565static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1566{
1567 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1568
1569 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1570
1571 return nsp_bus_reset(data);
1572}
1573
1574static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1575{
1576 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1577
1578 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1579
1580 nsphw_init(data);
1581
1582 return SUCCESS;
1583}
1584
1585
1586/**********************************************************************
1587 PCMCIA functions
1588**********************************************************************/
1589
1590/*======================================================================
1591 nsp_cs_attach() creates an "instance" of the driver, allocating
1592 local data structures for one device. The device is registered
1593 with Card Services.
1594
1595 The dev_link structure is initialized, but we don't actually
1596 configure the card at this point -- we wait until we receive a
1597 card insertion event.
1598======================================================================*/
1599static dev_link_t *nsp_cs_attach(void)
1600{
1601 scsi_info_t *info;
1602 client_reg_t client_reg;
1603 dev_link_t *link;
1604 int ret;
1605 nsp_hw_data *data = &nsp_data_base;
1606
1607 nsp_dbg(NSP_DEBUG_INIT, "in");
1608
1609 /* Create new SCSI device */
1610 info = kmalloc(sizeof(*info), GFP_KERNEL);
1611 if (info == NULL) { return NULL; }
1612 memset(info, 0, sizeof(*info));
1613 link = &info->link;
1614 link->priv = info;
1615 data->ScsiInfo = info;
1616
1617 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1618
1619 /* The io structure describes IO port mapping */
1620 link->io.NumPorts1 = 0x10;
1621 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1622 link->io.IOAddrLines = 10; /* not used */
1623
1624 /* Interrupt setup */
1625 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1626 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1627
1628 /* Interrupt handler */
1629 link->irq.Handler = &nspintr;
1630 link->irq.Instance = info;
1631 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1632
1633 /* General socket configuration */
1634 link->conf.Attributes = CONF_ENABLE_IRQ;
1635 link->conf.Vcc = 50;
1636 link->conf.IntType = INT_MEMORY_AND_IO;
1637 link->conf.Present = PRESENT_OPTION;
1638
1639
1640 /* Register with Card Services */
1641 link->next = dev_list;
1642 dev_list = link;
1643 client_reg.dev_info = &dev_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 client_reg.Version = 0x0210;
1645 client_reg.event_callback_args.client_data = link;
1646 ret = pcmcia_register_client(&link->handle, &client_reg);
1647 if (ret != CS_SUCCESS) {
1648 cs_error(link->handle, RegisterClient, ret);
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001649 nsp_cs_detach(link->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 return NULL;
1651 }
1652
1653
1654 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1655 return link;
1656} /* nsp_cs_attach */
1657
1658
1659/*======================================================================
1660 This deletes a driver "instance". The device is de-registered
1661 with Card Services. If it has been released, all local data
1662 structures are freed. Otherwise, the structures will be freed
1663 when the device is released.
1664======================================================================*/
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001665static void nsp_cs_detach(struct pcmcia_device *p_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666{
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001667 dev_link_t *link = dev_to_instance(p_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 dev_link_t **linkp;
1669
1670 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1671
1672 /* Locate device structure */
1673 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1674 if (*linkp == link) {
1675 break;
1676 }
1677 }
1678 if (*linkp == NULL) {
1679 return;
1680 }
1681
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01001682 if (link->state & DEV_CONFIG) {
1683 ((scsi_info_t *)link->priv)->stop = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 nsp_cs_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 }
1686
1687 /* Unlink device structure, free bits */
1688 *linkp = link->next;
1689 kfree(link->priv);
1690 link->priv = NULL;
1691
1692} /* nsp_cs_detach */
1693
1694
1695/*======================================================================
1696 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1697 is received, to configure the PCMCIA socket, and to make the
1698 ethernet device available to the system.
1699======================================================================*/
1700#define CS_CHECK(fn, ret) \
1701do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1702/*====================================================================*/
1703static void nsp_cs_config(dev_link_t *link)
1704{
1705 client_handle_t handle = link->handle;
1706 scsi_info_t *info = link->priv;
1707 tuple_t tuple;
1708 cisparse_t parse;
1709 int last_ret, last_fn;
1710 unsigned char tuple_data[64];
1711 config_info_t conf;
1712 win_req_t req;
1713 memreq_t map;
1714 cistpl_cftable_entry_t dflt = { 0 };
1715 struct Scsi_Host *host;
1716 nsp_hw_data *data = &nsp_data_base;
1717#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
Christoph Hellwigf64a1812005-10-31 18:32:08 +01001718 struct scsi_device *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 dev_node_t **tail, *node;
1720#endif
1721
1722 nsp_dbg(NSP_DEBUG_INIT, "in");
1723
1724 tuple.DesiredTuple = CISTPL_CONFIG;
1725 tuple.Attributes = 0;
1726 tuple.TupleData = tuple_data;
1727 tuple.TupleDataMax = sizeof(tuple_data);
1728 tuple.TupleOffset = 0;
1729 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1730 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1731 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1732 link->conf.ConfigBase = parse.config.base;
1733 link->conf.Present = parse.config.rmask[0];
1734
1735 /* Configure card */
1736 link->state |= DEV_CONFIG;
1737
1738 /* Look up the current Vcc */
1739 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1740 link->conf.Vcc = conf.Vcc;
1741
1742 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1743 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1744 while (1) {
1745 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1746
1747 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1748 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1749 goto next_entry;
1750
1751 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1752 if (cfg->index == 0) { goto next_entry; }
1753 link->conf.ConfigIndex = cfg->index;
1754
1755 /* Does this card need audio output? */
1756 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1757 link->conf.Attributes |= CONF_ENABLE_SPKR;
1758 link->conf.Status = CCSR_AUDIO_ENA;
1759 }
1760
1761 /* Use power settings for Vcc and Vpp if present */
1762 /* Note that the CIS values need to be rescaled */
1763 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1764 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1765 goto next_entry;
1766 }
1767 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1768 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1769 goto next_entry;
1770 }
1771 }
1772
1773 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1774 link->conf.Vpp1 = link->conf.Vpp2 =
1775 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1776 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1777 link->conf.Vpp1 = link->conf.Vpp2 =
1778 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1779 }
1780
1781 /* Do we need to allocate an interrupt? */
1782 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1783 link->conf.Attributes |= CONF_ENABLE_IRQ;
1784 }
1785
1786 /* IO window settings */
1787 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1788 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1789 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1790 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1791 if (!(io->flags & CISTPL_IO_8BIT))
1792 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1793 if (!(io->flags & CISTPL_IO_16BIT))
1794 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1795 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1796 link->io.BasePort1 = io->win[0].base;
1797 link->io.NumPorts1 = io->win[0].len;
1798 if (io->nwin > 1) {
1799 link->io.Attributes2 = link->io.Attributes1;
1800 link->io.BasePort2 = io->win[1].base;
1801 link->io.NumPorts2 = io->win[1].len;
1802 }
1803 /* This reserves IO space but doesn't actually enable it */
1804 if (pcmcia_request_io(link->handle, &link->io) != 0)
1805 goto next_entry;
1806 }
1807
1808 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1809 cistpl_mem_t *mem =
1810 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1811 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1812 req.Attributes |= WIN_ENABLE;
1813 req.Base = mem->win[0].host_addr;
1814 req.Size = mem->win[0].len;
1815 if (req.Size < 0x1000) {
1816 req.Size = 0x1000;
1817 }
1818 req.AccessSpeed = 0;
1819 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1820 goto next_entry;
1821 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1822 if (pcmcia_map_mem_page(link->win, &map) != 0)
1823 goto next_entry;
1824
1825 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1826 data->MmioLength = req.Size;
1827 }
1828 /* If we got this far, we're cool! */
1829 break;
1830
1831 next_entry:
1832 nsp_dbg(NSP_DEBUG_INIT, "next");
1833
1834 if (link->io.NumPorts1) {
1835 pcmcia_release_io(link->handle, &link->io);
1836 }
1837 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1838 }
1839
1840 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1841 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1842 }
1843 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1844
1845 if (free_ports) {
1846 if (link->io.BasePort1) {
1847 release_region(link->io.BasePort1, link->io.NumPorts1);
1848 }
1849 if (link->io.BasePort2) {
1850 release_region(link->io.BasePort2, link->io.NumPorts2);
1851 }
1852 }
1853
1854 /* Set port and IRQ */
1855 data->BaseAddress = link->io.BasePort1;
1856 data->NumAddress = link->io.NumPorts1;
1857 data->IrqNumber = link->irq.AssignedIRQ;
1858
1859 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1860 data->BaseAddress, data->NumAddress, data->IrqNumber);
1861
1862 if(nsphw_init(data) == FALSE) {
1863 goto cs_failed;
1864 }
1865
1866#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1867 host = nsp_detect(&nsp_driver_template);
1868#else
1869 scsi_register_host(&nsp_driver_template);
1870 for (host = scsi_host_get_next(NULL); host != NULL;
1871 host = scsi_host_get_next(host)) {
1872 if (host->hostt == &nsp_driver_template) {
1873 break;
1874 }
1875 }
1876#endif
1877
1878 if (host == NULL) {
1879 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1880 goto cs_failed;
1881 }
1882
1883
1884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1885 scsi_add_host (host, NULL);
1886 scsi_scan_host(host);
1887
1888 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1889 link->dev = &info->node;
1890 info->host = host;
1891
1892#else
1893 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1894 tail = &link->dev;
1895 info->ndev = 0;
1896
1897 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1898
1899 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1900 unsigned long id;
1901 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1902 ((dev->channel & 0x0f) << 8) +
1903 ((dev->host->host_no & 0x0f) << 12);
1904 node = &info->node[info->ndev];
1905 node->minor = 0;
1906 switch (dev->type) {
1907 case TYPE_TAPE:
1908 node->major = SCSI_TAPE_MAJOR;
1909 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1910 break;
1911 case TYPE_DISK:
1912 case TYPE_MOD:
1913 node->major = SCSI_DISK0_MAJOR;
1914 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1915 break;
1916 case TYPE_ROM:
1917 case TYPE_WORM:
1918 node->major = SCSI_CDROM_MAJOR;
1919 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1920 break;
1921 default:
1922 node->major = SCSI_GENERIC_MAJOR;
1923 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1924 break;
1925 }
1926 *tail = node; tail = &node->next;
1927 info->ndev++;
1928 info->host = dev->host;
1929 }
1930
1931 *tail = NULL;
1932 if (info->ndev == 0) {
1933 nsp_msg(KERN_INFO, "no SCSI devices found");
1934 }
1935 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1936#endif
1937
1938 /* Finally, report what we've done */
1939 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1940 link->conf.ConfigIndex,
1941 link->conf.Vcc/10, link->conf.Vcc%10);
1942 if (link->conf.Vpp1) {
1943 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1944 }
1945 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1946 printk(", irq %d", link->irq.AssignedIRQ);
1947 }
1948 if (link->io.NumPorts1) {
1949 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1950 link->io.BasePort1+link->io.NumPorts1-1);
1951 }
1952 if (link->io.NumPorts2)
1953 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1954 link->io.BasePort2+link->io.NumPorts2-1);
1955 if (link->win)
1956 printk(", mem 0x%06lx-0x%06lx", req.Base,
1957 req.Base+req.Size-1);
1958 printk("\n");
1959
1960 link->state &= ~DEV_CONFIG_PENDING;
1961 return;
1962
1963 cs_failed:
1964 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1965 cs_error(link->handle, last_fn, last_ret);
1966 nsp_cs_release(link);
1967
1968 return;
1969} /* nsp_cs_config */
1970#undef CS_CHECK
1971
1972
1973/*======================================================================
1974 After a card is removed, nsp_cs_release() will unregister the net
1975 device, and release the PCMCIA configuration. If the device is
1976 still open, this will be postponed until it is closed.
1977======================================================================*/
1978static void nsp_cs_release(dev_link_t *link)
1979{
1980 scsi_info_t *info = link->priv;
1981 nsp_hw_data *data = NULL;
1982
1983 if (info->host == NULL) {
1984 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1985 } else {
1986 data = (nsp_hw_data *)info->host->hostdata;
1987 }
1988
1989 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1990
1991 /* Unlink the device chain */
1992#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1993 if (info->host != NULL) {
1994 scsi_remove_host(info->host);
1995 }
1996#else
1997 scsi_unregister_host(&nsp_driver_template);
1998#endif
1999 link->dev = NULL;
2000
2001 if (link->win) {
2002 if (data != NULL) {
2003 iounmap((void *)(data->MmioAddress));
2004 }
2005 pcmcia_release_window(link->win);
2006 }
2007 pcmcia_release_configuration(link->handle);
2008 if (link->io.NumPorts1) {
2009 pcmcia_release_io(link->handle, &link->io);
2010 }
2011 if (link->irq.AssignedIRQ) {
2012 pcmcia_release_irq(link->handle, &link->irq);
2013 }
2014 link->state &= ~DEV_CONFIG;
2015#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2016 if (info->host != NULL) {
2017 scsi_host_put(info->host);
2018 }
2019#endif
2020} /* nsp_cs_release */
2021
Dominik Brodowski98e4c282005-11-14 21:21:18 +01002022static int nsp_cs_suspend(struct pcmcia_device *dev)
2023{
2024 dev_link_t *link = dev_to_instance(dev);
2025 scsi_info_t *info = link->priv;
2026 nsp_hw_data *data;
2027
2028 link->state |= DEV_SUSPEND;
2029
2030 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2031
2032 if (info->host != NULL) {
2033 nsp_msg(KERN_INFO, "clear SDTR status");
2034
2035 data = (nsp_hw_data *)info->host->hostdata;
2036
2037 nsphw_init_sync(data);
2038 }
2039
2040 info->stop = 1;
2041
2042 if (link->state & DEV_CONFIG)
2043 pcmcia_release_configuration(link->handle);
2044
2045 return 0;
2046}
2047
2048static int nsp_cs_resume(struct pcmcia_device *dev)
2049{
2050 dev_link_t *link = dev_to_instance(dev);
2051 scsi_info_t *info = link->priv;
2052 nsp_hw_data *data;
2053
2054 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2055
2056 link->state &= ~DEV_SUSPEND;
2057
2058 if (link->state & DEV_CONFIG)
2059 pcmcia_request_configuration(link->handle, &link->conf);
2060
2061 info->stop = 0;
2062
2063 if (info->host != NULL) {
2064 nsp_msg(KERN_INFO, "reset host and bus");
2065
2066 data = (nsp_hw_data *)info->host->hostdata;
2067
2068 nsphw_init (data);
2069 nsp_bus_reset(data);
2070 }
2071
2072 return 0;
2073}
2074
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075/*======================================================================
2076
2077 The card status event handler. Mostly, this schedules other
2078 stuff to run after an event is received. A CARD_REMOVAL event
2079 also sets some flags to discourage the net drivers from trying
2080 to talk to the card any more.
2081
2082 When a CARD_REMOVAL event is received, we immediately set a flag
2083 to block future accesses to this device. All the functions that
2084 actually access the device should check this flag to make sure
2085 the card is still present.
2086
2087======================================================================*/
2088static int nsp_cs_event(event_t event,
2089 int priority,
2090 event_callback_args_t *args)
2091{
2092 dev_link_t *link = args->client_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093
2094 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2095
2096 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 case CS_EVENT_CARD_INSERTION:
2098 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2099 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2100#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2101 info->bus = args->bus;
2102#endif
2103 nsp_cs_config(link);
2104 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 default:
2106 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2107 break;
2108 }
2109 nsp_dbg(NSP_DEBUG_INIT, "end");
2110 return 0;
2111} /* nsp_cs_event */
2112
2113/*======================================================================*
2114 * module entry point
2115 *====================================================================*/
2116#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
Dominik Brodowskiaba14102005-06-27 16:28:40 -07002117static struct pcmcia_device_id nsp_cs_ids[] = {
2118 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
2119 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
2120 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
2121 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
2122 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
2123 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
2124 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
2125 PCMCIA_DEVICE_NULL
2126};
2127MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2128
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129static struct pcmcia_driver nsp_driver = {
Dominik Brodowski1e212f32005-07-07 17:59:00 -07002130 .owner = THIS_MODULE,
2131 .drv = {
2132 .name = "nsp_cs",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 },
Dominik Brodowski1e212f32005-07-07 17:59:00 -07002134 .attach = nsp_cs_attach,
2135 .event = nsp_cs_event,
Dominik Brodowskicc3b4862005-11-14 21:23:14 +01002136 .remove = nsp_cs_detach,
Dominik Brodowskiaba14102005-06-27 16:28:40 -07002137 .id_table = nsp_cs_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +01002138 .suspend = nsp_cs_suspend,
2139 .resume = nsp_cs_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140};
2141#endif
2142
2143static int __init nsp_cs_init(void)
2144{
2145#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2146 nsp_msg(KERN_INFO, "loading...");
2147
2148 return pcmcia_register_driver(&nsp_driver);
2149#else
2150 servinfo_t serv;
2151
2152 nsp_msg(KERN_INFO, "loading...");
2153 pcmcia_get_card_services_info(&serv);
Pavel Roskin2ffe6e22005-07-07 17:59:04 -07002154 if (serv.Revision != CS_RELEASE_CODE) {
2155 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2156 return -EINVAL;
2157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2159
2160 nsp_dbg(NSP_DEBUG_INIT, "out");
2161 return 0;
2162#endif
2163}
2164
2165static void __exit nsp_cs_exit(void)
2166{
2167 nsp_msg(KERN_INFO, "unloading...");
2168
2169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2170 pcmcia_unregister_driver(&nsp_driver);
2171 BUG_ON(dev_list != NULL);
2172#else
2173 unregister_pcmcia_driver(&dev_info);
2174 /* XXX: this really needs to move into generic code.. */
2175 while (dev_list != NULL) {
2176 if (dev_list->state & DEV_CONFIG) {
2177 nsp_cs_release(dev_list);
2178 }
2179 nsp_cs_detach(dev_list);
2180 }
2181#endif
2182}
2183
2184
2185module_init(nsp_cs_init)
2186module_exit(nsp_cs_exit)
2187
2188/* end */