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