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