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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* imm.c   --  low level driver for the IOMEGA MatchMaker
2
 * parallel port SCSI host adapter.
3
 *
4
 * (The IMM is the embedded controller in the ZIP Plus drive.)
5
 *
6
 * Current Maintainer: David Campbell (Perth, Western Australia)
7
 *                     campbell@torque.net
8
 *
9
 * My unoffical company acronym list is 21 pages long:
10
 *      FLA:    Four letter acronym with built in facility for
11
 *              future expansion to five letters.
12
 */
13
 
14
#include <linux/config.h>
15
 
16
/* The following #define is to avoid a clash with hosts.c */
17
#define IMM_CODE 1
18
#define IMM_PROBE_SPP   0x0001
19
#define IMM_PROBE_PS2   0x0002
20
#define IMM_PROBE_ECR   0x0010
21
#define IMM_PROBE_EPP17 0x0100
22
#define IMM_PROBE_EPP19 0x0200
23
 
24
void imm_reset_pulse(unsigned int base);
25
static int device_check(int host_no);
26
 
27
#include <linux/blk.h>
28
#include <asm/io.h>
29
#include <linux/parport.h>
30
#include "sd.h"
31
#include "hosts.h"
32
typedef struct {
33
    struct pardevice *dev;      /* Parport device entry         */
34
    int base;                   /* Actual port address          */
35
    int base_hi;                /* Hi Base address for ECP-ISA chipset */
36
    int mode;                   /* Transfer mode                */
37
    int host;                   /* Host number (for proc)       */
38
    Scsi_Cmnd *cur_cmd;         /* Current queued command       */
39
    struct tq_struct imm_tq;    /* Polling interrupt stuff       */
40
    unsigned long jstart;       /* Jiffies at start             */
41
    unsigned failed:1;          /* Failure flag                 */
42
    unsigned dp:1;              /* Data phase present           */
43
    unsigned rd:1;              /* Read data in data phase      */
44
    unsigned p_busy:1;          /* Parport sharing busy flag    */
45
} imm_struct;
46
 
47
#define IMM_EMPTY \
48
{       dev:            NULL,           \
49
        base:           -1,             \
50
        base_hi:        0,               \
51
        mode:           IMM_AUTODETECT, \
52
        host:           -1,             \
53
        cur_cmd:        NULL,           \
54
        imm_tq:         { routine: imm_interrupt },    \
55
        jstart:         0,               \
56
        failed:         0,               \
57
        dp:             0,               \
58
        rd:             0,               \
59
        p_busy:         0                \
60
}
61
 
62
#include "imm.h"
63
#define NO_HOSTS 4
64
static imm_struct imm_hosts[NO_HOSTS] =
65
{IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
66
 
67
#define IMM_BASE(x)     imm_hosts[(x)].base
68
#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
69
 
70
int parbus_base[NO_HOSTS] =
71
{0x03bc, 0x0378, 0x0278, 0x0000};
72
 
73
void imm_wakeup(void *ref)
74
{
75
    imm_struct *imm_dev = (imm_struct *) ref;
76
 
77
    if (!imm_dev->p_busy)
78
        return;
79
 
80
    if (parport_claim(imm_dev->dev)) {
81
        printk("imm: bug in imm_wakeup\n");
82
        return;
83
    }
84
    imm_dev->p_busy = 0;
85
    imm_dev->base = imm_dev->dev->port->base;
86
    if (imm_dev->cur_cmd)
87
        imm_dev->cur_cmd->SCp.phase++;
88
    return;
89
}
90
 
91
int imm_release(struct Scsi_Host *host)
92
{
93
    int host_no = host->unique_id;
94
 
95
    printk("Releasing imm%i\n", host_no);
96
    parport_unregister_device(imm_hosts[host_no].dev);
97
    return 0;
98
}
99
 
100
static int imm_pb_claim(int host_no)
101
{
102
    if (parport_claim(imm_hosts[host_no].dev)) {
103
        imm_hosts[host_no].p_busy = 1;
104
        return 1;
105
    }
106
    if (imm_hosts[host_no].cur_cmd)
107
        imm_hosts[host_no].cur_cmd->SCp.phase++;
108
    return 0;
109
}
110
 
111
#define imm_pb_release(x) parport_release(imm_hosts[(x)].dev)
112
 
113
/***************************************************************************
114
 *                   Parallel port probing routines                        *
115
 ***************************************************************************/
116
 
117
static Scsi_Host_Template driver_template = IMM;
118
#include  "scsi_module.c"
119
 
120
int imm_detect(Scsi_Host_Template * host)
121
{
122
    struct Scsi_Host *hreg;
123
    int ports;
124
    int i, nhosts, try_again;
125
    struct parport *pb;
126
 
127
    /*
128
     * unlock to allow the lowlevel parport driver to probe
129
     * the irqs
130
     */
131
    spin_unlock_irq(&io_request_lock);
132
    pb = parport_enumerate();
133
 
134
    printk("imm: Version %s\n", IMM_VERSION);
135
    nhosts = 0;
136
    try_again = 0;
137
 
138
    if (!pb) {
139
        printk("imm: parport reports no devices.\n");
140
        spin_lock_irq(&io_request_lock);
141
        return 0;
142
    }
143
  retry_entry:
144
    for (i = 0; pb; i++, pb = pb->next) {
145
        int modes, ppb;
146
 
147
        imm_hosts[i].dev =
148
            parport_register_device(pb, "imm", NULL, imm_wakeup,
149
                                    NULL, 0, (void *) &imm_hosts[i]);
150
 
151
        if (!imm_hosts[i].dev)
152
            continue;
153
 
154
        /* Claim the bus so it remembers what we do to the control
155
         * registers. [ CTR and ECP ]
156
         */
157
        if (imm_pb_claim(i)) {
158
            unsigned long now = jiffies;
159
            while (imm_hosts[i].p_busy) {
160
                schedule();     /* We are safe to schedule here */
161
                if (time_after(jiffies, now + 3 * HZ)) {
162
                    printk(KERN_ERR "imm%d: failed to claim parport because a "
163
                      "pardevice is owning the port for too longtime!\n",
164
                           i);
165
                    parport_unregister_device (imm_hosts[i].dev);
166
                    spin_lock_irq(&io_request_lock);
167
                    return 0;
168
                }
169
            }
170
        }
171
        ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
172
        IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
173
        w_ctr(ppb, 0x0c);
174
        modes = imm_hosts[i].dev->port->modes;
175
 
176
        /* Mode detection works up the chain of speed
177
         * This avoids a nasty if-then-else-if-... tree
178
         */
179
        imm_hosts[i].mode = IMM_NIBBLE;
180
 
181
        if (modes & PARPORT_MODE_TRISTATE)
182
            imm_hosts[i].mode = IMM_PS2;
183
 
184
        /* Done configuration */
185
        imm_pb_release(i);
186
 
187
        if (imm_init(i)) {
188
            parport_unregister_device(imm_hosts[i].dev);
189
            continue;
190
        }
191
        /* now the glue ... */
192
        switch (imm_hosts[i].mode) {
193
        case IMM_NIBBLE:
194
            ports = 3;
195
            break;
196
        case IMM_PS2:
197
            ports = 3;
198
            break;
199
        case IMM_EPP_8:
200
        case IMM_EPP_16:
201
        case IMM_EPP_32:
202
            ports = 8;
203
            break;
204
        default:                /* Never gets here */
205
            continue;
206
        }
207
 
208
        host->can_queue = IMM_CAN_QUEUE;
209
        host->sg_tablesize = imm_sg;
210
        hreg = scsi_register(host, 0);
211
        if(hreg == NULL)
212
                continue;
213
        hreg->io_port = pb->base;
214
        hreg->n_io_port = ports;
215
        hreg->dma_channel = -1;
216
        hreg->unique_id = i;
217
        imm_hosts[i].host = hreg->host_no;
218
        nhosts++;
219
    }
220
    if (nhosts == 0) {
221
        if (try_again == 1) {
222
            spin_lock_irq(&io_request_lock);
223
            return 0;
224
        }
225
        try_again = 1;
226
        goto retry_entry;
227
    } else {
228
        spin_lock_irq (&io_request_lock);
229
        return 1;               /* return number of hosts detected */
230
    }
231
}
232
 
233
/* This is to give the imm driver a way to modify the timings (and other
234
 * parameters) by writing to the /proc/scsi/imm/0 file.
235
 * Very simple method really... (To simple, no error checking :( )
236
 * Reason: Kernel hackers HATE having to unload and reload modules for
237
 * testing...
238
 * Also gives a method to use a script to obtain optimum timings (TODO)
239
 */
240
static inline int imm_proc_write(int hostno, char *buffer, int length)
241
{
242
    unsigned long x;
243
 
244
    if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
245
        x = simple_strtoul(buffer + 5, NULL, 0);
246
        imm_hosts[hostno].mode = x;
247
        return length;
248
    }
249
    printk("imm /proc: invalid variable\n");
250
    return (-EINVAL);
251
}
252
 
253
int imm_proc_info(char *buffer, char **start, off_t offset,
254
                  int length, int hostno, int inout)
255
{
256
    int i;
257
    int len = 0;
258
 
259
    for (i = 0; i < 4; i++)
260
        if (imm_hosts[i].host == hostno)
261
            break;
262
 
263
    if (inout)
264
        return imm_proc_write(i, buffer, length);
265
 
266
    len += sprintf(buffer + len, "Version : %s\n", IMM_VERSION);
267
    len += sprintf(buffer + len, "Parport : %s\n", imm_hosts[i].dev->port->name);
268
    len += sprintf(buffer + len, "Mode    : %s\n", IMM_MODE_STRING[imm_hosts[i].mode]);
269
 
270
    /* Request for beyond end of buffer */
271
    if (offset > len)
272
        return 0;
273
 
274
    *start = buffer + offset;
275
    len -= offset;
276
    if (len > length)
277
        len = length;
278
    return len;
279
}
280
 
281
#if IMM_DEBUG > 0
282
#define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\
283
           y, __FUNCTION__, __LINE__); imm_fail_func(x,y);
284
static inline void imm_fail_func(int host_no, int error_code)
285
#else
286
static inline void imm_fail(int host_no, int error_code)
287
#endif
288
{
289
    /* If we fail a device then we trash status / message bytes */
290
    if (imm_hosts[host_no].cur_cmd) {
291
        imm_hosts[host_no].cur_cmd->result = error_code << 16;
292
        imm_hosts[host_no].failed = 1;
293
    }
294
}
295
 
296
/*
297
 * Wait for the high bit to be set.
298
 *
299
 * In principle, this could be tied to an interrupt, but the adapter
300
 * doesn't appear to be designed to support interrupts.  We spin on
301
 * the 0x80 ready bit.
302
 */
303
static unsigned char imm_wait(int host_no)
304
{
305
    int k;
306
    unsigned short ppb = IMM_BASE(host_no);
307
    unsigned char r;
308
 
309
    w_ctr(ppb, 0x0c);
310
 
311
    k = IMM_SPIN_TMO;
312
    do {
313
        r = r_str(ppb);
314
        k--;
315
        udelay(1);
316
    }
317
    while (!(r & 0x80) && (k));
318
 
319
    /*
320
     * STR register (LPT base+1) to SCSI mapping:
321
     *
322
     * STR      imm     imm
323
     * ===================================
324
     * 0x80     S_REQ   S_REQ
325
     * 0x40     !S_BSY  (????)
326
     * 0x20     !S_CD   !S_CD
327
     * 0x10     !S_IO   !S_IO
328
     * 0x08     (????)  !S_BSY
329
     *
330
     * imm      imm     meaning
331
     * ==================================
332
     * 0xf0     0xb8    Bit mask
333
     * 0xc0     0x88    ZIP wants more data
334
     * 0xd0     0x98    ZIP wants to send more data
335
     * 0xe0     0xa8    ZIP is expecting SCSI command data
336
     * 0xf0     0xb8    end of transfer, ZIP is sending status
337
     */
338
    w_ctr(ppb, 0x04);
339
    if (k)
340
        return (r & 0xb8);
341
 
342
    /* Counter expired - Time out occurred */
343
    imm_fail(host_no, DID_TIME_OUT);
344
    printk("imm timeout in imm_wait\n");
345
    return 0;                    /* command timed out */
346
}
347
 
348
static int imm_negotiate(imm_struct * tmp)
349
{
350
    /*
351
     * The following is supposedly the IEEE 1284-1994 negotiate
352
     * sequence. I have yet to obtain a copy of the above standard
353
     * so this is a bit of a guess...
354
     *
355
     * A fair chunk of this is based on the Linux parport implementation
356
     * of IEEE 1284.
357
     *
358
     * Return 0 if data available
359
     *        1 if no data available
360
     */
361
 
362
    unsigned short base = tmp->base;
363
    unsigned char a, mode;
364
 
365
    switch (tmp->mode) {
366
    case IMM_NIBBLE:
367
        mode = 0x00;
368
        break;
369
    case IMM_PS2:
370
        mode = 0x01;
371
        break;
372
    default:
373
        return 0;
374
    }
375
 
376
    w_ctr(base, 0x04);
377
    udelay(5);
378
    w_dtr(base, mode);
379
    udelay(100);
380
    w_ctr(base, 0x06);
381
    udelay(5);
382
    a = (r_str(base) & 0x20) ? 0 : 1;
383
    udelay(5);
384
    w_ctr(base, 0x07);
385
    udelay(5);
386
    w_ctr(base, 0x06);
387
 
388
    if (a) {
389
        printk("IMM: IEEE1284 negotiate indicates no data available.\n");
390
        imm_fail(tmp->host, DID_ERROR);
391
    }
392
    return a;
393
}
394
 
395
/*
396
 * Clear EPP timeout bit.
397
 */
398
static inline void epp_reset(unsigned short ppb)
399
{
400
    int i;
401
 
402
    i = r_str(ppb);
403
    w_str(ppb, i);
404
    w_str(ppb, i & 0xfe);
405
}
406
 
407
/*
408
 * Wait for empty ECP fifo (if we are in ECP fifo mode only)
409
 */
410
static inline void ecp_sync(unsigned short hostno)
411
{
412
    int i, ppb_hi=IMM_BASE_HI(hostno);
413
 
414
    if (ppb_hi == 0) return;
415
 
416
    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
417
        for (i = 0; i < 100; i++) {
418
            if (r_ecr(ppb_hi) & 0x01)
419
                return;
420
            udelay(5);
421
        }
422
        printk("imm: ECP sync failed as data still present in FIFO.\n");
423
    }
424
}
425
 
426
static int imm_byte_out(unsigned short base, const char *buffer, int len)
427
{
428
    int i;
429
 
430
    w_ctr(base, 0x4);           /* apparently a sane mode */
431
    for (i = len >> 1; i; i--) {
432
        w_dtr(base, *buffer++);
433
        w_ctr(base, 0x5);       /* Drop STROBE low */
434
        w_dtr(base, *buffer++);
435
        w_ctr(base, 0x0);       /* STROBE high + INIT low */
436
    }
437
    w_ctr(base, 0x4);           /* apparently a sane mode */
438
    return 1;                   /* All went well - we hope! */
439
}
440
 
441
static int imm_nibble_in(unsigned short base, char *buffer, int len)
442
{
443
    unsigned char l;
444
    int i;
445
 
446
    /*
447
     * The following is based on documented timing signals
448
     */
449
    w_ctr(base, 0x4);
450
    for (i = len; i; i--) {
451
        w_ctr(base, 0x6);
452
        l = (r_str(base) & 0xf0) >> 4;
453
        w_ctr(base, 0x5);
454
        *buffer++ = (r_str(base) & 0xf0) | l;
455
        w_ctr(base, 0x4);
456
    }
457
    return 1;                   /* All went well - we hope! */
458
}
459
 
460
static int imm_byte_in(unsigned short base, char *buffer, int len)
461
{
462
    int i;
463
 
464
    /*
465
     * The following is based on documented timing signals
466
     */
467
    w_ctr(base, 0x4);
468
    for (i = len; i; i--) {
469
        w_ctr(base, 0x26);
470
        *buffer++ = r_dtr(base);
471
        w_ctr(base, 0x25);
472
    }
473
    return 1;                   /* All went well - we hope! */
474
}
475
 
476
static int imm_out(int host_no, char *buffer, int len)
477
{
478
    int r;
479
    unsigned short ppb = IMM_BASE(host_no);
480
 
481
    r = imm_wait(host_no);
482
 
483
    /*
484
     * Make sure that:
485
     * a) the SCSI bus is BUSY (device still listening)
486
     * b) the device is listening
487
     */
488
    if ((r & 0x18) != 0x08) {
489
        imm_fail(host_no, DID_ERROR);
490
        printk("IMM: returned SCSI status %2x\n", r);
491
        return 0;
492
    }
493
    switch (imm_hosts[host_no].mode) {
494
    case IMM_EPP_32:
495
    case IMM_EPP_16:
496
    case IMM_EPP_8:
497
        epp_reset(ppb);
498
        w_ctr(ppb, 0x4);
499
#ifdef CONFIG_SCSI_IZIP_EPP16
500
        if (!(((long) buffer | len) & 0x01))
501
            outsw(ppb + 4, buffer, len >> 1);
502
#else
503
        if (!(((long) buffer | len) & 0x03))
504
            outsl(ppb + 4, buffer, len >> 2);
505
#endif
506
        else
507
            outsb(ppb + 4, buffer, len);
508
        w_ctr(ppb, 0xc);
509
        r = !(r_str(ppb) & 0x01);
510
        w_ctr(ppb, 0xc);
511
        ecp_sync(host_no);
512
        break;
513
 
514
    case IMM_NIBBLE:
515
    case IMM_PS2:
516
        /* 8 bit output, with a loop */
517
        r = imm_byte_out(ppb, buffer, len);
518
        break;
519
 
520
    default:
521
        printk("IMM: bug in imm_out()\n");
522
        r = 0;
523
    }
524
    return r;
525
}
526
 
527
static int imm_in(int host_no, char *buffer, int len)
528
{
529
    int r;
530
    unsigned short ppb = IMM_BASE(host_no);
531
 
532
    r = imm_wait(host_no);
533
 
534
    /*
535
     * Make sure that:
536
     * a) the SCSI bus is BUSY (device still listening)
537
     * b) the device is sending data
538
     */
539
    if ((r & 0x18) != 0x18) {
540
        imm_fail(host_no, DID_ERROR);
541
        return 0;
542
    }
543
    switch (imm_hosts[host_no].mode) {
544
    case IMM_NIBBLE:
545
        /* 4 bit input, with a loop */
546
        r = imm_nibble_in(ppb, buffer, len);
547
        w_ctr(ppb, 0xc);
548
        break;
549
 
550
    case IMM_PS2:
551
        /* 8 bit input, with a loop */
552
        r = imm_byte_in(ppb, buffer, len);
553
        w_ctr(ppb, 0xc);
554
        break;
555
 
556
    case IMM_EPP_32:
557
    case IMM_EPP_16:
558
    case IMM_EPP_8:
559
        epp_reset(ppb);
560
        w_ctr(ppb, 0x24);
561
#ifdef CONFIG_SCSI_IZIP_EPP16
562
        if (!(((long) buffer | len) & 0x01))
563
            insw(ppb + 4, buffer, len >> 1);
564
#else
565
        if (!(((long) buffer | len) & 0x03))
566
            insl(ppb + 4, buffer, len >> 2);
567
#endif
568
        else
569
            insb(ppb + 4, buffer, len);
570
        w_ctr(ppb, 0x2c);
571
        r = !(r_str(ppb) & 0x01);
572
        w_ctr(ppb, 0x2c);
573
        ecp_sync(host_no);
574
        break;
575
 
576
    default:
577
        printk("IMM: bug in imm_ins()\n");
578
        r = 0;
579
        break;
580
    }
581
    return r;
582
}
583
 
584
static int imm_cpp(unsigned short ppb, unsigned char b)
585
{
586
    /*
587
     * Comments on udelay values refer to the
588
     * Command Packet Protocol (CPP) timing diagram.
589
     */
590
 
591
    unsigned char s1, s2, s3;
592
    w_ctr(ppb, 0x0c);
593
    udelay(2);                  /* 1 usec - infinite */
594
    w_dtr(ppb, 0xaa);
595
    udelay(10);                 /* 7 usec - infinite */
596
    w_dtr(ppb, 0x55);
597
    udelay(10);                 /* 7 usec - infinite */
598
    w_dtr(ppb, 0x00);
599
    udelay(10);                 /* 7 usec - infinite */
600
    w_dtr(ppb, 0xff);
601
    udelay(10);                 /* 7 usec - infinite */
602
    s1 = r_str(ppb) & 0xb8;
603
    w_dtr(ppb, 0x87);
604
    udelay(10);                 /* 7 usec - infinite */
605
    s2 = r_str(ppb) & 0xb8;
606
    w_dtr(ppb, 0x78);
607
    udelay(10);                 /* 7 usec - infinite */
608
    s3 = r_str(ppb) & 0x38;
609
    /*
610
     * Values for b are:
611
     * 0000 00aa    Assign address aa to current device
612
     * 0010 00aa    Select device aa in EPP Winbond mode
613
     * 0010 10aa    Select device aa in EPP mode
614
     * 0011 xxxx    Deselect all devices
615
     * 0110 00aa    Test device aa
616
     * 1101 00aa    Select device aa in ECP mode
617
     * 1110 00aa    Select device aa in Compatible mode
618
     */
619
    w_dtr(ppb, b);
620
    udelay(2);                  /* 1 usec - infinite */
621
    w_ctr(ppb, 0x0c);
622
    udelay(10);                 /* 7 usec - infinite */
623
    w_ctr(ppb, 0x0d);
624
    udelay(2);                  /* 1 usec - infinite */
625
    w_ctr(ppb, 0x0c);
626
    udelay(10);                 /* 7 usec - infinite */
627
    w_dtr(ppb, 0xff);
628
    udelay(10);                 /* 7 usec - infinite */
629
 
630
    /*
631
     * The following table is electrical pin values.
632
     * (BSY is inverted at the CTR register)
633
     *
634
     *       BSY  ACK  POut SEL  Fault
635
     * S1    0    X    1    1    1
636
     * S2    1    X    0    1    1
637
     * S3    L    X    1    1    S
638
     *
639
     * L => Last device in chain
640
     * S => Selected
641
     *
642
     * Observered values for S1,S2,S3 are:
643
     * Disconnect => f8/58/78
644
     * Connect    => f8/58/70
645
     */
646
    if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30))
647
        return 1;               /* Connected */
648
    if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38))
649
        return 0;                /* Disconnected */
650
 
651
    return -1;                  /* No device present */
652
}
653
 
654
static inline int imm_connect(int host_no, int flag)
655
{
656
    unsigned short ppb = IMM_BASE(host_no);
657
 
658
    imm_cpp(ppb, 0xe0);         /* Select device 0 in compatible mode */
659
    imm_cpp(ppb, 0x30);         /* Disconnect all devices */
660
 
661
    if ((imm_hosts[host_no].mode == IMM_EPP_8) ||
662
        (imm_hosts[host_no].mode == IMM_EPP_16) ||
663
        (imm_hosts[host_no].mode == IMM_EPP_32))
664
        return imm_cpp(ppb, 0x28);      /* Select device 0 in EPP mode */
665
    return imm_cpp(ppb, 0xe0);  /* Select device 0 in compatible mode */
666
}
667
 
668
static void imm_disconnect(int host_no)
669
{
670
    unsigned short ppb = IMM_BASE(host_no);
671
 
672
    imm_cpp(ppb, 0x30);         /* Disconnect all devices */
673
}
674
 
675
static int imm_select(int host_no, int target)
676
{
677
    int k;
678
    unsigned short ppb = IMM_BASE(host_no);
679
 
680
    /*
681
     * Firstly we want to make sure there is nothing
682
     * holding onto the SCSI bus.
683
     */
684
    w_ctr(ppb, 0xc);
685
 
686
    k = IMM_SELECT_TMO;
687
    do {
688
        k--;
689
    } while ((r_str(ppb) & 0x08) && (k));
690
 
691
    if (!k)
692
        return 0;
693
 
694
    /*
695
     * Now assert the SCSI ID (HOST and TARGET) on the data bus
696
     */
697
    w_ctr(ppb, 0x4);
698
    w_dtr(ppb, 0x80 | (1 << target));
699
    udelay(1);
700
 
701
    /*
702
     * Deassert SELIN first followed by STROBE
703
     */
704
    w_ctr(ppb, 0xc);
705
    w_ctr(ppb, 0xd);
706
 
707
    /*
708
     * ACK should drop low while SELIN is deasserted.
709
     * FAULT should drop low when the SCSI device latches the bus.
710
     */
711
    k = IMM_SELECT_TMO;
712
    do {
713
        k--;
714
    }
715
    while (!(r_str(ppb) & 0x08) && (k));
716
 
717
    /*
718
     * Place the interface back into a sane state (status mode)
719
     */
720
    w_ctr(ppb, 0xc);
721
    return (k) ? 1 : 0;
722
}
723
 
724
static int imm_init(int host_no)
725
{
726
    int retv;
727
 
728
#if defined(CONFIG_PARPORT) || defined(CONFIG_PARPORT_MODULE)
729
    if (imm_pb_claim(host_no))
730
        while (imm_hosts[host_no].p_busy)
731
            schedule();         /* We can safe schedule here */
732
#endif
733
    retv = imm_connect(host_no, 0);
734
 
735
    if (retv == 1) {
736
        imm_reset_pulse(IMM_BASE(host_no));
737
        udelay(1000);           /* Delay to allow devices to settle */
738
        imm_disconnect(host_no);
739
        udelay(1000);           /* Another delay to allow devices to settle */
740
        retv = device_check(host_no);
741
        imm_pb_release(host_no);
742
        return retv;
743
    }
744
    imm_pb_release(host_no);
745
    return 1;
746
}
747
 
748
static inline int imm_send_command(Scsi_Cmnd * cmd)
749
{
750
    int host_no = cmd->host->unique_id;
751
    int k;
752
 
753
    /* NOTE: IMM uses byte pairs */
754
    for (k = 0; k < cmd->cmd_len; k += 2)
755
        if (!imm_out(host_no, &cmd->cmnd[k], 2))
756
            return 0;
757
    return 1;
758
}
759
 
760
/*
761
 * The bulk flag enables some optimisations in the data transfer loops,
762
 * it should be true for any command that transfers data in integral
763
 * numbers of sectors.
764
 *
765
 * The driver appears to remain stable if we speed up the parallel port
766
 * i/o in this function, but not elsewhere.
767
 */
768
static int imm_completion(Scsi_Cmnd * cmd)
769
{
770
    /* Return codes:
771
     * -1     Error
772
     *  0     Told to schedule
773
     *  1     Finished data transfer
774
     */
775
    int host_no = cmd->host->unique_id;
776
    unsigned short ppb = IMM_BASE(host_no);
777
    unsigned long start_jiffies = jiffies;
778
 
779
    unsigned char r, v;
780
    int fast, bulk, status;
781
 
782
    v = cmd->cmnd[0];
783
    bulk = ((v == READ_6) ||
784
            (v == READ_10) ||
785
            (v == WRITE_6) ||
786
            (v == WRITE_10));
787
 
788
    /*
789
     * We only get here if the drive is ready to comunicate,
790
     * hence no need for a full imm_wait.
791
     */
792
    w_ctr(ppb, 0x0c);
793
    r = (r_str(ppb) & 0xb8);
794
 
795
    /*
796
     * while (device is not ready to send status byte)
797
     *     loop;
798
     */
799
    while (r != (unsigned char) 0xb8) {
800
        /*
801
         * If we have been running for more than a full timer tick
802
         * then take a rest.
803
         */
804
        if (time_after(jiffies, start_jiffies + 1))
805
            return 0;
806
 
807
        /*
808
         * FAIL if:
809
         * a) Drive status is screwy (!ready && !present)
810
         * b) Drive is requesting/sending more data than expected
811
         */
812
        if (((r & 0x88) != 0x88) || (cmd->SCp.this_residual <= 0)) {
813
            imm_fail(host_no, DID_ERROR);
814
            return -1;          /* ERROR_RETURN */
815
        }
816
        /* determine if we should use burst I/O */
817
        if (imm_hosts[host_no].rd == 0) {
818
            fast = (bulk && (cmd->SCp.this_residual >= IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 2;
819
            status = imm_out(host_no, cmd->SCp.ptr, fast);
820
        } else {
821
            fast = (bulk && (cmd->SCp.this_residual >= IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 1;
822
            status = imm_in(host_no, cmd->SCp.ptr, fast);
823
        }
824
 
825
        cmd->SCp.ptr += fast;
826
        cmd->SCp.this_residual -= fast;
827
 
828
        if (!status) {
829
            imm_fail(host_no, DID_BUS_BUSY);
830
            return -1;          /* ERROR_RETURN */
831
        }
832
        if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
833
            /* if scatter/gather, advance to the next segment */
834
            if (cmd->SCp.buffers_residual--) {
835
                cmd->SCp.buffer++;
836
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
837
                cmd->SCp.ptr = cmd->SCp.buffer->address;
838
 
839
                /*
840
                 * Make sure that we transfer even number of bytes
841
                 * otherwise it makes imm_byte_out() messy.
842
                 */
843
                if (cmd->SCp.this_residual & 0x01)
844
                    cmd->SCp.this_residual++;
845
            }
846
        }
847
        /* Now check to see if the drive is ready to comunicate */
848
        w_ctr(ppb, 0x0c);
849
        r = (r_str(ppb) & 0xb8);
850
 
851
        /* If not, drop back down to the scheduler and wait a timer tick */
852
        if (!(r & 0x80))
853
            return 0;
854
    }
855
    return 1;                   /* FINISH_RETURN */
856
}
857
 
858
/* deprecated synchronous interface */
859
int imm_command(Scsi_Cmnd * cmd)
860
{
861
    static int first_pass = 1;
862
    int host_no = cmd->host->unique_id;
863
 
864
    if (first_pass) {
865
        printk("imm: using non-queuing interface\n");
866
        first_pass = 0;
867
    }
868
    if (imm_hosts[host_no].cur_cmd) {
869
        printk("IMM: bug in imm_command\n");
870
        return 0;
871
    }
872
    imm_hosts[host_no].failed = 0;
873
    imm_hosts[host_no].jstart = jiffies;
874
    imm_hosts[host_no].cur_cmd = cmd;
875
    cmd->result = DID_ERROR << 16;      /* default return code */
876
    cmd->SCp.phase = 0;
877
 
878
    imm_pb_claim(host_no);
879
 
880
    while (imm_engine(&imm_hosts[host_no], cmd))
881
        schedule();
882
 
883
    if (cmd->SCp.phase)         /* Only disconnect if we have connected */
884
        imm_disconnect(cmd->host->unique_id);
885
 
886
    imm_pb_release(host_no);
887
    imm_hosts[host_no].cur_cmd = 0;
888
    return cmd->result;
889
}
890
 
891
/*
892
 * Since the IMM itself doesn't generate interrupts, we use
893
 * the scheduler's task queue to generate a stream of call-backs and
894
 * complete the request when the drive is ready.
895
 */
896
static void imm_interrupt(void *data)
897
{
898
    imm_struct *tmp = (imm_struct *) data;
899
    Scsi_Cmnd *cmd = tmp->cur_cmd;
900
    unsigned long flags;
901
 
902
    if (!cmd) {
903
        printk("IMM: bug in imm_interrupt\n");
904
        return;
905
    }
906
    if (imm_engine(tmp, cmd)) {
907
        tmp->imm_tq.data = (void *) tmp;
908
        tmp->imm_tq.sync = 0;
909
        queue_task(&tmp->imm_tq, &tq_timer);
910
        return;
911
    }
912
    /* Command must of completed hence it is safe to let go... */
913
#if IMM_DEBUG > 0
914
    switch ((cmd->result >> 16) & 0xff) {
915
    case DID_OK:
916
        break;
917
    case DID_NO_CONNECT:
918
        printk("imm: no device at SCSI ID %i\n", cmd->target);
919
        break;
920
    case DID_BUS_BUSY:
921
        printk("imm: BUS BUSY - EPP timeout detected\n");
922
        break;
923
    case DID_TIME_OUT:
924
        printk("imm: unknown timeout\n");
925
        break;
926
    case DID_ABORT:
927
        printk("imm: told to abort\n");
928
        break;
929
    case DID_PARITY:
930
        printk("imm: parity error (???)\n");
931
        break;
932
    case DID_ERROR:
933
        printk("imm: internal driver error\n");
934
        break;
935
    case DID_RESET:
936
        printk("imm: told to reset device\n");
937
        break;
938
    case DID_BAD_INTR:
939
        printk("imm: bad interrupt (???)\n");
940
        break;
941
    default:
942
        printk("imm: bad return code (%02x)\n", (cmd->result >> 16) & 0xff);
943
    }
944
#endif
945
 
946
    if (cmd->SCp.phase > 1)
947
        imm_disconnect(cmd->host->unique_id);
948
    if (cmd->SCp.phase > 0)
949
        imm_pb_release(cmd->host->unique_id);
950
 
951
    spin_lock_irqsave(&io_request_lock, flags);
952
    tmp->cur_cmd = 0;
953
    cmd->scsi_done(cmd);
954
    spin_unlock_irqrestore(&io_request_lock, flags);
955
    return;
956
}
957
 
958
static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd)
959
{
960
    int host_no = cmd->host->unique_id;
961
    unsigned short ppb = IMM_BASE(host_no);
962
    unsigned char l = 0, h = 0;
963
    int retv, x;
964
 
965
    /* First check for any errors that may of occurred
966
     * Here we check for internal errors
967
     */
968
    if (tmp->failed)
969
        return 0;
970
 
971
    switch (cmd->SCp.phase) {
972
    case 0:                      /* Phase 0 - Waiting for parport */
973
        if ((jiffies - tmp->jstart) > HZ) {
974
            /*
975
             * We waited more than a second
976
             * for parport to call us
977
             */
978
            imm_fail(host_no, DID_BUS_BUSY);
979
            return 0;
980
        }
981
        return 1;               /* wait until imm_wakeup claims parport */
982
        /* Phase 1 - Connected */
983
    case 1:
984
        imm_connect(host_no, CONNECT_EPP_MAYBE);
985
        cmd->SCp.phase++;
986
 
987
        /* Phase 2 - We are now talking to the scsi bus */
988
    case 2:
989
        if (!imm_select(host_no, cmd->target)) {
990
            imm_fail(host_no, DID_NO_CONNECT);
991
            return 0;
992
        }
993
        cmd->SCp.phase++;
994
 
995
        /* Phase 3 - Ready to accept a command */
996
    case 3:
997
        w_ctr(ppb, 0x0c);
998
        if (!(r_str(ppb) & 0x80))
999
            return 1;
1000
 
1001
        if (!imm_send_command(cmd))
1002
            return 0;
1003
        cmd->SCp.phase++;
1004
 
1005
        /* Phase 4 - Setup scatter/gather buffers */
1006
    case 4:
1007
        if (cmd->use_sg) {
1008
            /* if many buffers are available, start filling the first */
1009
            cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
1010
            cmd->SCp.this_residual = cmd->SCp.buffer->length;
1011
            cmd->SCp.ptr = cmd->SCp.buffer->address;
1012
        } else {
1013
            /* else fill the only available buffer */
1014
            cmd->SCp.buffer = NULL;
1015
            cmd->SCp.this_residual = cmd->request_bufflen;
1016
            cmd->SCp.ptr = cmd->request_buffer;
1017
        }
1018
        cmd->SCp.buffers_residual = cmd->use_sg;
1019
        cmd->SCp.phase++;
1020
        if (cmd->SCp.this_residual & 0x01)
1021
            cmd->SCp.this_residual++;
1022
        /* Phase 5 - Pre-Data transfer stage */
1023
    case 5:
1024
        /* Spin lock for BUSY */
1025
        w_ctr(ppb, 0x0c);
1026
        if (!(r_str(ppb) & 0x80))
1027
            return 1;
1028
 
1029
        /* Require negotiation for read requests */
1030
        x = (r_str(ppb) & 0xb8);
1031
        tmp->rd = (x & 0x10) ? 1 : 0;
1032
        tmp->dp = (x & 0x20) ? 0 : 1;
1033
 
1034
        if ((tmp->dp) && (tmp->rd))
1035
            if (imm_negotiate(tmp))
1036
                return 0;
1037
        cmd->SCp.phase++;
1038
 
1039
        /* Phase 6 - Data transfer stage */
1040
    case 6:
1041
        /* Spin lock for BUSY */
1042
        w_ctr(ppb, 0x0c);
1043
        if (!(r_str(ppb) & 0x80))
1044
            return 1;
1045
 
1046
        if (tmp->dp) {
1047
            retv = imm_completion(cmd);
1048
            if (retv == -1)
1049
                return 0;
1050
            if (retv == 0)
1051
                return 1;
1052
        }
1053
        cmd->SCp.phase++;
1054
 
1055
        /* Phase 7 - Post data transfer stage */
1056
    case 7:
1057
        if ((tmp->dp) && (tmp->rd)) {
1058
            if ((tmp->mode == IMM_NIBBLE) || (tmp->mode == IMM_PS2)) {
1059
                w_ctr(ppb, 0x4);
1060
                w_ctr(ppb, 0xc);
1061
                w_ctr(ppb, 0xe);
1062
                w_ctr(ppb, 0x4);
1063
            }
1064
        }
1065
        cmd->SCp.phase++;
1066
 
1067
        /* Phase 8 - Read status/message */
1068
    case 8:
1069
        /* Check for data overrun */
1070
        if (imm_wait(host_no) != (unsigned char) 0xb8) {
1071
            imm_fail(host_no, DID_ERROR);
1072
            return 0;
1073
        }
1074
        if (imm_negotiate(tmp))
1075
            return 0;
1076
        if (imm_in(host_no, &l, 1)) {   /* read status byte */
1077
            /* Check for optional message byte */
1078
            if (imm_wait(host_no) == (unsigned char) 0xb8)
1079
                imm_in(host_no, &h, 1);
1080
            cmd->result = (DID_OK << 16) + (l & STATUS_MASK);
1081
        }
1082
        if ((tmp->mode == IMM_NIBBLE) || (tmp->mode == IMM_PS2)) {
1083
            w_ctr(ppb, 0x4);
1084
            w_ctr(ppb, 0xc);
1085
            w_ctr(ppb, 0xe);
1086
            w_ctr(ppb, 0x4);
1087
        }
1088
        return 0;                /* Finished */
1089
        break;
1090
 
1091
    default:
1092
        printk("imm: Invalid scsi phase\n");
1093
    }
1094
    return 0;
1095
}
1096
 
1097
int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
1098
{
1099
    int host_no = cmd->host->unique_id;
1100
 
1101
    if (imm_hosts[host_no].cur_cmd) {
1102
        printk("IMM: bug in imm_queuecommand\n");
1103
        return 0;
1104
    }
1105
    imm_hosts[host_no].failed = 0;
1106
    imm_hosts[host_no].jstart = jiffies;
1107
    imm_hosts[host_no].cur_cmd = cmd;
1108
    cmd->scsi_done = done;
1109
    cmd->result = DID_ERROR << 16;      /* default return code */
1110
    cmd->SCp.phase = 0;          /* bus free */
1111
 
1112
    imm_pb_claim(host_no);
1113
 
1114
    imm_hosts[host_no].imm_tq.data = imm_hosts + host_no;
1115
    imm_hosts[host_no].imm_tq.sync = 0;
1116
    queue_task(&imm_hosts[host_no].imm_tq, &tq_immediate);
1117
    mark_bh(IMMEDIATE_BH);
1118
 
1119
    return 0;
1120
}
1121
 
1122
/*
1123
 * Apparently the disk->capacity attribute is off by 1 sector
1124
 * for all disk drives.  We add the one here, but it should really
1125
 * be done in sd.c.  Even if it gets fixed there, this will still
1126
 * work.
1127
 */
1128
int imm_biosparam(Disk * disk, kdev_t dev, int ip[])
1129
{
1130
    ip[0] = 0x40;
1131
    ip[1] = 0x20;
1132
    ip[2] = (disk->capacity + 1) / (ip[0] * ip[1]);
1133
    if (ip[2] > 1024) {
1134
        ip[0] = 0xff;
1135
        ip[1] = 0x3f;
1136
        ip[2] = (disk->capacity + 1) / (ip[0] * ip[1]);
1137
    }
1138
    return 0;
1139
}
1140
 
1141
int imm_abort(Scsi_Cmnd * cmd)
1142
{
1143
    int host_no = cmd->host->unique_id;
1144
    /*
1145
     * There is no method for aborting commands since Iomega
1146
     * have tied the SCSI_MESSAGE line high in the interface
1147
     */
1148
 
1149
    switch (cmd->SCp.phase) {
1150
    case 0:                      /* Do not have access to parport */
1151
    case 1:                     /* Have not connected to interface */
1152
        imm_hosts[host_no].cur_cmd = NULL;      /* Forget the problem */
1153
        return SUCCESS;
1154
        break;
1155
    default:                    /* SCSI command sent, can not abort */
1156
        return FAILED;
1157
        break;
1158
    }
1159
}
1160
 
1161
void imm_reset_pulse(unsigned int base)
1162
{
1163
    w_ctr(base, 0x04);
1164
    w_dtr(base, 0x40);
1165
    udelay(1);
1166
    w_ctr(base, 0x0c);
1167
    w_ctr(base, 0x0d);
1168
    udelay(50);
1169
    w_ctr(base, 0x0c);
1170
    w_ctr(base, 0x04);
1171
}
1172
 
1173
int imm_reset(Scsi_Cmnd * cmd)
1174
{
1175
    int host_no = cmd->host->unique_id;
1176
 
1177
    if (cmd->SCp.phase)
1178
        imm_disconnect(host_no);
1179
    imm_hosts[host_no].cur_cmd = NULL;  /* Forget the problem */
1180
 
1181
    imm_connect(host_no, CONNECT_NORMAL);
1182
    imm_reset_pulse(IMM_BASE(host_no));
1183
    udelay(1000);               /* device settle delay */
1184
    imm_disconnect(host_no);
1185
    udelay(1000);               /* device settle delay */
1186
    return SUCCESS;
1187
}
1188
 
1189
static int device_check(int host_no)
1190
{
1191
    /* This routine looks for a device and then attempts to use EPP
1192
       to send a command. If all goes as planned then EPP is available. */
1193
 
1194
    static char cmd[6] =
1195
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1196
    int loop, old_mode, status, k, ppb = IMM_BASE(host_no);
1197
    unsigned char l;
1198
 
1199
    old_mode = imm_hosts[host_no].mode;
1200
    for (loop = 0; loop < 8; loop++) {
1201
        /* Attempt to use EPP for Test Unit Ready */
1202
        if ((ppb & 0x0007) == 0x0000)
1203
            imm_hosts[host_no].mode = IMM_EPP_32;
1204
 
1205
      second_pass:
1206
        imm_connect(host_no, CONNECT_EPP_MAYBE);
1207
        /* Select SCSI device */
1208
        if (!imm_select(host_no, loop)) {
1209
            imm_disconnect(host_no);
1210
            continue;
1211
        }
1212
        printk("imm: Found device at ID %i, Attempting to use %s\n", loop,
1213
               IMM_MODE_STRING[imm_hosts[host_no].mode]);
1214
 
1215
        /* Send SCSI command */
1216
        status = 1;
1217
        w_ctr(ppb, 0x0c);
1218
        for (l = 0; (l < 3) && (status); l++)
1219
            status = imm_out(host_no, &cmd[l << 1], 2);
1220
 
1221
        if (!status) {
1222
            imm_disconnect(host_no);
1223
            imm_connect(host_no, CONNECT_EPP_MAYBE);
1224
            imm_reset_pulse(IMM_BASE(host_no));
1225
            udelay(1000);
1226
            imm_disconnect(host_no);
1227
            udelay(1000);
1228
            if (imm_hosts[host_no].mode == IMM_EPP_32) {
1229
                imm_hosts[host_no].mode = old_mode;
1230
                goto second_pass;
1231
            }
1232
            printk("imm: Unable to establish communication, aborting driver load.\n");
1233
            return 1;
1234
        }
1235
        w_ctr(ppb, 0x0c);
1236
 
1237
        k = 1000000;            /* 1 Second */
1238
        do {
1239
            l = r_str(ppb);
1240
            k--;
1241
            udelay(1);
1242
        } while (!(l & 0x80) && (k));
1243
 
1244
        l &= 0xb8;
1245
 
1246
        if (l != 0xb8) {
1247
            imm_disconnect(host_no);
1248
            imm_connect(host_no, CONNECT_EPP_MAYBE);
1249
            imm_reset_pulse(IMM_BASE(host_no));
1250
            udelay(1000);
1251
            imm_disconnect(host_no);
1252
            udelay(1000);
1253
            if (imm_hosts[host_no].mode == IMM_EPP_32) {
1254
                imm_hosts[host_no].mode = old_mode;
1255
                goto second_pass;
1256
            }
1257
            printk("imm: Unable to establish communication, aborting driver load.\n");
1258
            return 1;
1259
        }
1260
        imm_disconnect(host_no);
1261
        printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
1262
               IMM_MODE_STRING[imm_hosts[host_no].mode]);
1263
        imm_connect(host_no, CONNECT_EPP_MAYBE);
1264
        imm_reset_pulse(IMM_BASE(host_no));
1265
        udelay(1000);
1266
        imm_disconnect(host_no);
1267
        udelay(1000);
1268
        return 0;
1269
    }
1270
    printk("imm: No devices found, aborting driver load.\n");
1271
    return 1;
1272
}
1273
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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