Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/scsi/pcmcia/nsp_cs.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us