OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [pcmcia/] [nsp_cs.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.