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 <../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
  56MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
  57MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
  58MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
  59#ifdef MODULE_LICENSE
  60MODULE_LICENSE("GPL");
  61#endif
  62
  63#include "nsp_io.h"
  64
  65/*====================================================================*/
  66/* Parameters that can be set with 'insmod' */
  67
  68static int       nsp_burst_mode = BURST_MEM32;
  69module_param(nsp_burst_mode, int, 0);
  70MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
  71
  72/* Release IO ports after configuration? */
  73static int       free_ports = 0;
  74module_param(free_ports, bool, 0);
  75MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
  76
  77static struct scsi_host_template nsp_driver_template = {
  78        .proc_name               = "nsp_cs",
  79        .proc_info               = nsp_proc_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
  93static 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
 135static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
 136{
 137        scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
 138}
 139
 140static 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
 157static 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 */
 178static 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
 187static 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=%d sglist=0x%p bufflen=%d sg_count=%d",
 199                SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
 200                scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
 201        //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
 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
 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, 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
 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 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 */
 365static 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
 421struct 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
 428static 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
 436static 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 */
 446static 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 */
 504static 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 */
 517static 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 timeut", str);
 537        }
 538
 539        return 0;
 540}
 541
 542/*
 543 * expect Ninja Irq
 544 */
 545static 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 */
 580static 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 */
 620static 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 */
 652static 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 */
 691static 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 */
 718static 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 avilable ? */
 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 */
 817static 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 */
 914static 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 */
 956static 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
1302timer_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/*----------------------------------------------------------------*/
1314static 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/*----------------------------------------------------------------*/
1360static 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...) \
1369        do { \
1370                if(length > (pos - buffer)) { \
1371                        pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1372                        nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
1373                } \
1374        } while(0)
1375
1376static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start,
1377                         off_t offset, int length, int inout)
1378{
1379        int id;
1380        char *pos = buffer;
1381        int thislength;
1382        int speed;
1383        unsigned long flags;
1384        nsp_hw_data *data;
1385        int hostno;
1386
1387        if (inout) {
1388                return -EINVAL;
1389        }
1390
1391        hostno = host->host_no;
1392        data = (nsp_hw_data *)host->hostdata;
1393
1394
1395        SPRINTF("NinjaSCSI status\n\n");
1396        SPRINTF("Driver version:        $Revision: 1.23 $\n");
1397        SPRINTF("SCSI host No.:         %d\n",          hostno);
1398        SPRINTF("IRQ:                   %d\n",          host->irq);
1399        SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1400        SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1401        SPRINTF("sg_tablesize:          %d\n",          host->sg_tablesize);
1402
1403        SPRINTF("burst transfer mode:   ");
1404        switch (nsp_burst_mode) {
1405        case BURST_IO8:
1406                SPRINTF("io8");
1407                break;
1408        case BURST_IO32:
1409                SPRINTF("io32");
1410                break;
1411        case BURST_MEM32:
1412                SPRINTF("mem32");
1413                break;
1414        default:
1415                SPRINTF("???");
1416                break;
1417        }
1418        SPRINTF("\n");
1419
1420
1421        spin_lock_irqsave(&(data->Lock), flags);
1422        SPRINTF("CurrentSC:             0x%p\n\n",      data->CurrentSC);
1423        spin_unlock_irqrestore(&(data->Lock), flags);
1424
1425        SPRINTF("SDTR status\n");
1426        for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1427
1428                SPRINTF("id %d: ", id);
1429
1430                if (id == host->this_id) {
1431                        SPRINTF("----- NinjaSCSI-3 host adapter\n");
1432                        continue;
1433                }
1434
1435                switch(data->Sync[id].SyncNegotiation) {
1436                case SYNC_OK:
1437                        SPRINTF(" sync");
1438                        break;
1439                case SYNC_NG:
1440                        SPRINTF("async");
1441                        break;
1442                case SYNC_NOT_YET:
1443                        SPRINTF(" none");
1444                        break;
1445                default:
1446                        SPRINTF("?????");
1447                        break;
1448                }
1449
1450                if (data->Sync[id].SyncPeriod != 0) {
1451                        speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1452
1453                        SPRINTF(" transfer %d.%dMB/s, offset %d",
1454                                speed / 1000,
1455                                speed % 1000,
1456                                data->Sync[id].SyncOffset
1457                                );
1458                }
1459                SPRINTF("\n");
1460        }
1461
1462        thislength = pos - (buffer + offset);
1463
1464        if(thislength < 0) {
1465                *start = NULL;
1466                return 0;
1467        }
1468
1469
1470        thislength = min(thislength, length);
1471        *start = buffer + offset;
1472
1473        return thislength;
1474}
1475#undef SPRINTF
1476
1477/*---------------------------------------------------------------*/
1478/* error handler                                                 */
1479/*---------------------------------------------------------------*/
1480
1481/*
1482static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1483{
1484        nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1485
1486        return nsp_eh_bus_reset(SCpnt);
1487}*/
1488
1489static int nsp_bus_reset(nsp_hw_data *data)
1490{
1491        unsigned int base = data->BaseAddress;
1492        int          i;
1493
1494        nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1495
1496        nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1497        mdelay(100); /* 100ms */
1498        nsp_index_write(base, SCSIBUSCTRL, 0);
1499        for(i = 0; i < 5; i++) {
1500                nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1501        }
1502
1503        nsphw_init_sync(data);
1504
1505        nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1506
1507        return SUCCESS;
1508}
1509
1510static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1511{
1512        nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1513
1514        nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1515
1516        return nsp_bus_reset(data);
1517}
1518
1519static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1520{
1521        nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1522
1523        nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1524
1525        nsphw_init(data);
1526
1527        return SUCCESS;
1528}
1529
1530
1531/**********************************************************************
1532  PCMCIA functions
1533**********************************************************************/
1534
1535static int nsp_cs_probe(struct pcmcia_device *link)
1536{
1537        scsi_info_t  *info;
1538        nsp_hw_data  *data = &nsp_data_base;
1539        int ret;
1540
1541        nsp_dbg(NSP_DEBUG_INIT, "in");
1542
1543        /* Create new SCSI device */
1544        info = kzalloc(sizeof(*info), GFP_KERNEL);
1545        if (info == NULL) { return -ENOMEM; }
1546        info->p_dev = link;
1547        link->priv = info;
1548        data->ScsiInfo = info;
1549
1550        nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1551
1552        ret = nsp_cs_config(link);
1553
1554        nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1555        return ret;
1556} /* nsp_cs_attach */
1557
1558
1559static void nsp_cs_detach(struct pcmcia_device *link)
1560{
1561        nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1562
1563        ((scsi_info_t *)link->priv)->stop = 1;
1564        nsp_cs_release(link);
1565
1566        kfree(link->priv);
1567        link->priv = NULL;
1568} /* nsp_cs_detach */
1569
1570
1571static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1572{
1573        nsp_hw_data             *data = priv_data;
1574
1575        if (p_dev->config_index == 0)
1576                return -ENODEV;
1577
1578        /* This reserves IO space but doesn't actually enable it */
1579        if (pcmcia_request_io(p_dev) != 0)
1580                goto next_entry;
1581
1582        if (resource_size(p_dev->resource[2])) {
1583                p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1584                                        WIN_MEMORY_TYPE_CM |
1585                                        WIN_ENABLE);
1586                if (p_dev->resource[2]->end < 0x1000)
1587                        p_dev->resource[2]->end = 0x1000;
1588                if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1589                        goto next_entry;
1590                if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
1591                                                p_dev->card_addr) != 0)
1592                        goto next_entry;
1593
1594                data->MmioAddress = (unsigned long)
1595                        ioremap_nocache(p_dev->resource[2]->start,
1596                                        resource_size(p_dev->resource[2]));
1597                data->MmioLength  = resource_size(p_dev->resource[2]);
1598        }
1599        /* If we got this far, we're cool! */
1600        return 0;
1601
1602next_entry:
1603        nsp_dbg(NSP_DEBUG_INIT, "next");
1604        pcmcia_disable_device(p_dev);
1605        return -ENODEV;
1606}
1607
1608static int nsp_cs_config(struct pcmcia_device *link)
1609{
1610        int               ret;
1611        scsi_info_t      *info   = link->priv;
1612        struct Scsi_Host *host;
1613        nsp_hw_data      *data = &nsp_data_base;
1614
1615        nsp_dbg(NSP_DEBUG_INIT, "in");
1616
1617        link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1618                CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1619                CONF_AUTO_SET_IO;
1620
1621        ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
1622        if (ret)
1623                goto cs_failed;
1624
1625        if (pcmcia_request_irq(link, nspintr))
1626                goto cs_failed;
1627
1628        ret = pcmcia_enable_device(link);
1629        if (ret)
1630                goto cs_failed;
1631
1632        if (free_ports) {
1633                if (link->resource[0]) {
1634                        release_region(link->resource[0]->start,
1635                                        resource_size(link->resource[0]));
1636                }
1637                if (link->resource[1]) {
1638                        release_region(link->resource[1]->start,
1639                                        resource_size(link->resource[1]));
1640                }
1641        }
1642
1643        /* Set port and IRQ */
1644        data->BaseAddress = link->resource[0]->start;
1645        data->NumAddress  = resource_size(link->resource[0]);
1646        data->IrqNumber   = link->irq;
1647
1648        nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1649                data->BaseAddress, data->NumAddress, data->IrqNumber);
1650
1651        if(nsphw_init(data) == FALSE) {
1652                goto cs_failed;
1653        }
1654
1655        host = nsp_detect(&nsp_driver_template);
1656
1657        if (host == NULL) {
1658                nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1659                goto cs_failed;
1660        }
1661
1662
1663        ret = scsi_add_host (host, NULL);
1664        if (ret)
1665                goto cs_failed;
1666
1667        scsi_scan_host(host);
1668
1669        info->host = host;
1670
1671        return 0;
1672
1673 cs_failed:
1674        nsp_dbg(NSP_DEBUG_INIT, "config fail");
1675        nsp_cs_release(link);
1676
1677        return -ENODEV;
1678} /* nsp_cs_config */
1679
1680
1681static void nsp_cs_release(struct pcmcia_device *link)
1682{
1683        scsi_info_t *info = link->priv;
1684        nsp_hw_data *data = NULL;
1685
1686        if (info->host == NULL) {
1687                nsp_msg(KERN_DEBUG, "unexpected card release call.");
1688        } else {
1689                data = (nsp_hw_data *)info->host->hostdata;
1690        }
1691
1692        nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1693
1694        /* Unlink the device chain */
1695        if (info->host != NULL) {
1696                scsi_remove_host(info->host);
1697        }
1698
1699        if (resource_size(link->resource[2])) {
1700                if (data != NULL) {
1701                        iounmap((void *)(data->MmioAddress));
1702                }
1703        }
1704        pcmcia_disable_device(link);
1705
1706        if (info->host != NULL) {
1707                scsi_host_put(info->host);
1708        }
1709} /* nsp_cs_release */
1710
1711static int nsp_cs_suspend(struct pcmcia_device *link)
1712{
1713        scsi_info_t *info = link->priv;
1714        nsp_hw_data *data;
1715
1716        nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1717
1718        if (info->host != NULL) {
1719                nsp_msg(KERN_INFO, "clear SDTR status");
1720
1721                data = (nsp_hw_data *)info->host->hostdata;
1722
1723                nsphw_init_sync(data);
1724        }
1725
1726        info->stop = 1;
1727
1728        return 0;
1729}
1730
1731static int nsp_cs_resume(struct pcmcia_device *link)
1732{
1733        scsi_info_t *info = link->priv;
1734        nsp_hw_data *data;
1735
1736        nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1737
1738        info->stop = 0;
1739
1740        if (info->host != NULL) {
1741                nsp_msg(KERN_INFO, "reset host and bus");
1742
1743                data = (nsp_hw_data *)info->host->hostdata;
1744
1745                nsphw_init   (data);
1746                nsp_bus_reset(data);
1747        }
1748
1749        return 0;
1750}
1751
1752/*======================================================================*
1753 *      module entry point
1754 *====================================================================*/
1755static struct pcmcia_device_id nsp_cs_ids[] = {
1756        PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16       ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1757        PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1758        PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1759        PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1760        PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1761        PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1762        PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1763        PCMCIA_DEVICE_NULL
1764};
1765MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1766
1767static struct pcmcia_driver nsp_driver = {
1768        .owner          = THIS_MODULE,
1769        .name           = "nsp_cs",
1770        .probe          = nsp_cs_probe,
1771        .remove         = nsp_cs_detach,
1772        .id_table       = nsp_cs_ids,
1773        .suspend        = nsp_cs_suspend,
1774        .resume         = nsp_cs_resume,
1775};
1776
1777static int __init nsp_cs_init(void)
1778{
1779        return pcmcia_register_driver(&nsp_driver);
1780}
1781
1782static void __exit nsp_cs_exit(void)
1783{
1784        pcmcia_unregister_driver(&nsp_driver);
1785}
1786
1787
1788module_init(nsp_cs_init)
1789module_exit(nsp_cs_exit)
1790
1791/* end */
1792