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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: atp870u.c,v 1.1.1.1 2004-04-15 02:12:55 phoenix Exp $
2
 *  linux/kernel/atp870u.c
3
 *
4
 *  Copyright (C) 1997  Wu Ching Chen
5
 *  2.1.x update (C) 1998  Krzysztof G. Baranowski
6
 *
7
 * Marcelo Tosatti <marcelo@conectiva.com.br> : SMP fixes
8
 *
9
 * Wu Ching Chen : NULL pointer fixes  2000/06/02
10
 *                 support atp876 chip
11
 *                 enable 32 bit fifo transfer
12
 *                 support cdrom & remove device run ultra speed
13
 *                 fix disconnect bug  2000/12/21
14
 *                 support atp880 chip lvd u160 2001/05/15
15
 *                 fix prd table bug 2001/09/12 (7.1)
16
 */
17
 
18
#include <linux/module.h>
19
 
20
#include <linux/kernel.h>
21
#include <linux/types.h>
22
#include <linux/string.h>
23
#include <linux/ioport.h>
24
#include <linux/delay.h>
25
#include <linux/sched.h>
26
#include <linux/proc_fs.h>
27
#include <linux/spinlock.h>
28
#include <asm/system.h>
29
#include <asm/io.h>
30
#include <linux/pci.h>
31
#include <linux/blk.h>
32
#include "scsi.h"
33
#include "hosts.h"
34
 
35
 
36
#include "atp870u.h"
37
 
38
#include<linux/stat.h>
39
 
40
void mydlyu(unsigned int);
41
 
42
/*
43
 *   static const char RCSid[] = "$Header: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/linux/linux-2.4/drivers/scsi/atp870u.c,v 1.1.1.1 2004-04-15 02:12:55 phoenix Exp $";
44
 */
45
 
46
static unsigned char admaxu = 1;
47
static unsigned short int sync_idu;
48
 
49
static unsigned int irqnumu[2] = {0, 0};
50
 
51
struct atp_unit
52
{
53
        unsigned long ioport;
54
        unsigned long irq;
55
        unsigned long pciport;
56
        unsigned char last_cmd;
57
        unsigned char in_snd;
58
        unsigned char in_int;
59
        unsigned char quhdu;
60
        unsigned char quendu;
61
        unsigned char scam_on;
62
        unsigned char global_map;
63
        unsigned char chip_veru;
64
        unsigned char host_idu;
65
        int working;
66
        unsigned short wide_idu;
67
        unsigned short active_idu;
68
        unsigned short ultra_map;
69
        unsigned short async;
70
        unsigned short deviceid;
71
        unsigned char ata_cdbu[16];
72
        unsigned char sp[16];
73
        Scsi_Cmnd *querequ[qcnt];
74
        struct atp_id
75
        {
76
                unsigned char dirctu;
77
                unsigned char devspu;
78
                unsigned char devtypeu;
79
                unsigned long prdaddru;
80
                unsigned long tran_lenu;
81
                unsigned long last_lenu;
82
                unsigned char *prd_posu;
83
                unsigned char *prd_tableu;
84
                Scsi_Cmnd *curr_req;
85
        } id[16];
86
};
87
 
88
static struct Scsi_Host *atp_host[2] = {NULL, NULL};
89
static struct atp_unit atp_unit[2];
90
 
91
static void atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
92
{
93
        unsigned long flags;
94
        unsigned short int tmpcip, id;
95
        unsigned char i, j, h, target_id, lun;
96
        unsigned char *prd;
97
        Scsi_Cmnd *workrequ;
98
        unsigned int workportu, tmport;
99
        unsigned long adrcntu, k;
100
        int errstus;
101
        struct atp_unit *dev = dev_id;
102
 
103
        for (h = 0; h < 2; h++) {
104
                if (irq == irqnumu[h]) {
105
                        goto irq_numok;
106
                }
107
        }
108
        return;
109
irq_numok:
110
        dev->in_int = 1;
111
        workportu = dev->ioport;
112
        tmport = workportu;
113
 
114
        if (dev->working != 0)
115
        {
116
                tmport += 0x1f;
117
                j = inb(tmport);
118
                if ((j & 0x80) == 0)
119
                {
120
                        dev->in_int = 0;
121
                        return;
122
                }
123
 
124
                tmpcip = dev->pciport;
125
                if ((inb(tmpcip) & 0x08) != 0)
126
                {
127
                        tmpcip += 0x2;
128
                        for (k=0; k < 1000; k++)
129
                        {
130
                                if ((inb(tmpcip) & 0x08) == 0)
131
                                {
132
                                        goto stop_dma;
133
                                }
134
                                if ((inb(tmpcip) & 0x01) == 0)
135
                                {
136
                                        goto stop_dma;
137
                                }
138
                        }
139
                }
140
stop_dma:
141
                tmpcip = dev->pciport;
142
                outb(0x00, tmpcip);
143
                tmport -= 0x08;
144
 
145
                i = inb(tmport);
146
 
147
                tmport -= 0x02;
148
                target_id = inb(tmport);
149
                tmport += 0x02;
150
 
151
                /*
152
                 *      Remap wide devices onto id numbers
153
                 */
154
 
155
                if ((target_id & 0x40) != 0) {
156
                        target_id = (target_id & 0x07) | 0x08;
157
                } else {
158
                        target_id &= 0x07;
159
                }
160
 
161
                if ((j & 0x40) != 0)
162
                {
163
                     if (dev->last_cmd == 0xff)
164
                     {
165
                        dev->last_cmd = target_id;
166
                     }
167
                     dev->last_cmd |= 0x40;
168
                }
169
 
170
                if (i == 0x85)
171
                {
172
                        if ((dev->last_cmd & 0xf0) != 0x40)
173
                        {
174
                           dev->last_cmd = 0xff;
175
                        }
176
                        /*
177
                         *      Flip wide
178
                         */
179
                        if (dev->wide_idu != 0)
180
                        {
181
                                tmport = workportu + 0x1b;
182
                                outb(0x01,tmport);
183
                                while ((inb(tmport) & 0x01) != 0x01)
184
                                {
185
                                   outb(0x01,tmport);
186
                                }
187
                        }
188
                        /*
189
                         *      Issue more commands
190
                         */
191
                        if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) &&
192
                            (dev->in_snd == 0))
193
                        {
194
                                send_s870(h);
195
                        }
196
                        /*
197
                         *      Done
198
                         */
199
                        dev->in_int = 0;
200
                        return;
201
                }
202
 
203
                if (i == 0x40)
204
                {
205
                     dev->last_cmd |= 0x40;
206
                     dev->in_int = 0;
207
                     return;
208
                }
209
 
210
                if (i == 0x21)
211
                {
212
                        if ((dev->last_cmd & 0xf0) != 0x40)
213
                        {
214
                           dev->last_cmd = 0xff;
215
                        }
216
                        tmport -= 0x05;
217
                        adrcntu = 0;
218
                        ((unsigned char *) &adrcntu)[2] = inb(tmport++);
219
                        ((unsigned char *) &adrcntu)[1] = inb(tmport++);
220
                        ((unsigned char *) &adrcntu)[0] = inb(tmport);
221
                        k = dev->id[target_id].last_lenu;
222
                        k -= adrcntu;
223
                        dev->id[target_id].tran_lenu = k;
224
                        dev->id[target_id].last_lenu = adrcntu;
225
                        tmport -= 0x04;
226
                        outb(0x41, tmport);
227
                        tmport += 0x08;
228
                        outb(0x08, tmport);
229
                        dev->in_int = 0;
230
                        return;
231
                }
232
                if ((i == 0x80) || (i == 0x8f))
233
                {
234
                        lun = 0;
235
                        tmport -= 0x07;
236
                        j = inb(tmport);
237
                        if (j == 0x44 || i==0x80) {
238
                                tmport += 0x0d;
239
                                lun = inb(tmport) & 0x07;
240
                        } else {
241
                                if ((dev->last_cmd & 0xf0) != 0x40)
242
                                {
243
                                   dev->last_cmd = 0xff;
244
                                }
245
                                if (j == 0x41)
246
                                {
247
                                        tmport += 0x02;
248
                                        adrcntu = 0;
249
                                        ((unsigned char *) &adrcntu)[2] = inb(tmport++);
250
                                        ((unsigned char *) &adrcntu)[1] = inb(tmport++);
251
                                        ((unsigned char *) &adrcntu)[0] = inb(tmport);
252
                                        k = dev->id[target_id].last_lenu;
253
                                        k -= adrcntu;
254
                                        dev->id[target_id].tran_lenu = k;
255
                                        dev->id[target_id].last_lenu = adrcntu;
256
                                        tmport += 0x04;
257
                                        outb(0x08, tmport);
258
                                        dev->in_int = 0;
259
                                        return;
260
                                }
261
                                else
262
                                {
263
                                        outb(0x46, tmport);
264
                                        dev->id[target_id].dirctu = 0x00;
265
                                        tmport += 0x02;
266
                                        outb(0x00, tmport++);
267
                                        outb(0x00, tmport++);
268
                                        outb(0x00, tmport++);
269
                                        tmport += 0x03;
270
                                        outb(0x08, tmport);
271
                                        dev->in_int = 0;
272
                                        return;
273
                                }
274
                        }
275
                        if (dev->last_cmd != 0xff)
276
                        {
277
                           dev->last_cmd |= 0x40;
278
                        }
279
                        tmport = workportu + 0x10;
280
                        outb(0x45, tmport);
281
                        tmport += 0x06;
282
                        target_id = inb(tmport);
283
                        /*
284
                         *      Remap wide identifiers
285
                         */
286
                        if ((target_id & 0x10) != 0)
287
                        {
288
                                target_id = (target_id & 0x07) | 0x08;
289
                        } else {
290
                                target_id &= 0x07;
291
                        }
292
                        workrequ = dev->id[target_id].curr_req;
293
                        tmport = workportu + 0x0f;
294
                        outb(lun, tmport);
295
                        tmport += 0x02;
296
                        outb(dev->id[target_id].devspu, tmport++);
297
                        adrcntu = dev->id[target_id].tran_lenu;
298
                        k = dev->id[target_id].last_lenu;
299
                        outb(((unsigned char *) &k)[2], tmport++);
300
                        outb(((unsigned char *) &k)[1], tmport++);
301
                        outb(((unsigned char *) &k)[0], tmport++);
302
                        /* Remap wide */
303
                        j = target_id;
304
                        if (target_id > 7) {
305
                                j = (j & 0x07) | 0x40;
306
                        }
307
                        /* Add direction */
308
                        j |= dev->id[target_id].dirctu;
309
                        outb(j, tmport++);
310
                        outb(0x80, tmport);
311
 
312
                        /* enable 32 bit fifo transfer */
313
                        if (dev->deviceid != 0x8081)
314
                        {
315
                           tmport = workportu + 0x3a;
316
                           if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
317
                               (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
318
                           {
319
                              outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
320
                           }
321
                           else
322
                           {
323
                              outb((unsigned char)(inb(tmport) & 0xf3),tmport);
324
                           }
325
                        }
326
                        else
327
                        {
328
                           tmport = workportu - 0x05;
329
                           if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
330
                               (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
331
                           {
332
                              outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
333
                           }
334
                           else
335
                           {
336
                              outb((unsigned char)(inb(tmport) & 0x3f),tmport);
337
                           }
338
                        }
339
 
340
                        tmport = workportu + 0x1b;
341
                        j = 0;
342
                        id = 1;
343
                        id = id << target_id;
344
                        /*
345
                         *      Is this a wide device
346
                         */
347
                        if ((id & dev->wide_idu) != 0) {
348
                                j |= 0x01;
349
                        }
350
                        outb(j, tmport);
351
                        while ((inb(tmport) & 0x01) != j)
352
                        {
353
                           outb(j,tmport);
354
                        }
355
 
356
                        if (dev->id[target_id].last_lenu == 0) {
357
                                tmport = workportu + 0x18;
358
                                outb(0x08, tmport);
359
                                dev->in_int = 0;
360
                                return;
361
                        }
362
                        prd = dev->id[target_id].prd_posu;
363
                        while (adrcntu != 0)
364
                        {
365
                                id = ((unsigned short int *) (prd))[2];
366
                                if (id == 0) {
367
                                        k = 0x10000;
368
                                } else {
369
                                        k = id;
370
                                }
371
                                if (k > adrcntu) {
372
                                        ((unsigned short int *) (prd))[2] = (unsigned short int)
373
                                            (k - adrcntu);
374
                                        ((unsigned long *) (prd))[0] += adrcntu;
375
                                        adrcntu = 0;
376
                                        dev->id[target_id].prd_posu = prd;
377
                                } else {
378
                                        adrcntu -= k;
379
                                        dev->id[target_id].prdaddru += 0x08;
380
                                        prd += 0x08;
381
                                        if (adrcntu == 0) {
382
                                                dev->id[target_id].prd_posu = prd;
383
                                        }
384
                                }
385
                        }
386
                        tmpcip = dev->pciport + 0x04;
387
                        outl(dev->id[target_id].prdaddru, tmpcip);
388
                        tmpcip -= 0x02;
389
                        outb(0x06, tmpcip);
390
                        outb(0x00, tmpcip);
391
                        tmpcip -= 0x02;
392
                        tmport = workportu + 0x18;
393
                        /*
394
                         *      Check transfer direction
395
                         */
396
                        if (dev->id[target_id].dirctu != 0) {
397
                                outb(0x08, tmport);
398
                                outb(0x01, tmpcip);
399
                                dev->in_int = 0;
400
                                return;
401
                        }
402
                        outb(0x08, tmport);
403
                        outb(0x09, tmpcip);
404
                        dev->in_int = 0;
405
                        return;
406
                }
407
 
408
                /*
409
                 *      Current scsi request on this target
410
                 */
411
 
412
                workrequ = dev->id[target_id].curr_req;
413
 
414
                if (i == 0x42) {
415
                        if ((dev->last_cmd & 0xf0) != 0x40)
416
                        {
417
                           dev->last_cmd = 0xff;
418
                        }
419
                        errstus = 0x02;
420
                        workrequ->result = errstus;
421
                        goto go_42;
422
                }
423
                if (i == 0x16)
424
                {
425
                        if ((dev->last_cmd & 0xf0) != 0x40)
426
                        {
427
                           dev->last_cmd = 0xff;
428
                        }
429
                        errstus = 0;
430
                        tmport -= 0x08;
431
                        errstus = inb(tmport);
432
                        workrequ->result = errstus;
433
go_42:
434
                        /*
435
                         *      Complete the command
436
                         */
437
                        spin_lock_irqsave(&io_request_lock, flags);
438
                        (*workrequ->scsi_done) (workrequ);
439
 
440
                        /*
441
                         *      Clear it off the queue
442
                         */
443
                        dev->id[target_id].curr_req = 0;
444
                        dev->working--;
445
                        spin_unlock_irqrestore(&io_request_lock, flags);
446
                        /*
447
                         *      Take it back wide
448
                         */
449
                        if (dev->wide_idu != 0) {
450
                                tmport = workportu + 0x1b;
451
                                outb(0x01,tmport);
452
                                while ((inb(tmport) & 0x01) != 0x01)
453
                                {
454
                                   outb(0x01,tmport);
455
                                }
456
                        }
457
                        /*
458
                         *      If there is stuff to send and nothing going then send it
459
                         */
460
                        if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) &&
461
                            (dev->in_snd == 0))
462
                        {
463
                           send_s870(h);
464
                        }
465
                        dev->in_int = 0;
466
                        return;
467
                }
468
                if ((dev->last_cmd & 0xf0) != 0x40)
469
                {
470
                   dev->last_cmd = 0xff;
471
                }
472
                if (i == 0x4f) {
473
                        i = 0x89;
474
                }
475
                i &= 0x0f;
476
                if (i == 0x09) {
477
                        tmpcip = tmpcip + 4;
478
                        outl(dev->id[target_id].prdaddru, tmpcip);
479
                        tmpcip = tmpcip - 2;
480
                        outb(0x06, tmpcip);
481
                        outb(0x00, tmpcip);
482
                        tmpcip = tmpcip - 2;
483
                        tmport = workportu + 0x10;
484
                        outb(0x41, tmport);
485
                        dev->id[target_id].dirctu = 0x00;
486
                        tmport += 0x08;
487
                        outb(0x08, tmport);
488
                        outb(0x09, tmpcip);
489
                        dev->in_int = 0;
490
                        return;
491
                }
492
                if (i == 0x08) {
493
                        tmpcip = tmpcip + 4;
494
                        outl(dev->id[target_id].prdaddru, tmpcip);
495
                        tmpcip = tmpcip - 2;
496
                        outb(0x06, tmpcip);
497
                        outb(0x00, tmpcip);
498
                        tmpcip = tmpcip - 2;
499
                        tmport = workportu + 0x10;
500
                        outb(0x41, tmport);
501
                        tmport += 0x05;
502
                        outb((unsigned char) (inb(tmport) | 0x20), tmport);
503
                        dev->id[target_id].dirctu = 0x20;
504
                        tmport += 0x03;
505
                        outb(0x08, tmport);
506
                        outb(0x01, tmpcip);
507
                        dev->in_int = 0;
508
                        return;
509
                }
510
                tmport -= 0x07;
511
                if (i == 0x0a) {
512
                        outb(0x30, tmport);
513
                } else {
514
                        outb(0x46, tmport);
515
                }
516
                dev->id[target_id].dirctu = 0x00;
517
                tmport += 0x02;
518
                outb(0x00, tmport++);
519
                outb(0x00, tmport++);
520
                outb(0x00, tmport++);
521
                tmport += 0x03;
522
                outb(0x08, tmport);
523
                dev->in_int = 0;
524
                return;
525
        } else {
526
//              tmport = workportu + 0x17;
527
//              inb(tmport);
528
//              dev->working = 0;
529
                dev->in_int = 0;
530
                return;
531
        }
532
}
533
 
534
int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
535
{
536
        unsigned char h;
537
        unsigned long flags;
538
        unsigned short int m;
539
        unsigned int tmport;
540
        struct atp_unit *dev;
541
 
542
        for (h = 0; h <= admaxu; h++) {
543
                if (req_p->host == atp_host[h]) {
544
                        goto host_ok;
545
                }
546
        }
547
        return 0;
548
host_ok:
549
        if (req_p->channel != 0) {
550
                req_p->result = 0x00040000;
551
                done(req_p);
552
                return 0;
553
        }
554
        dev = &atp_unit[h];
555
        m = 1;
556
        m = m << req_p->target;
557
 
558
        /*
559
         *      Fake a timeout for missing targets
560
         */
561
 
562
        if ((m & dev->active_idu) == 0) {
563
                req_p->result = 0x00040000;
564
                done(req_p);
565
                return 0;
566
        }
567
        if (done) {
568
                req_p->scsi_done = done;
569
        } else {
570
                printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n");
571
                req_p->result = 0;
572
                done(req_p);
573
                return 0;
574
        }
575
        /*
576
         *      Count new command
577
         */
578
        save_flags(flags);
579
        cli();
580
        dev->quendu++;
581
        if (dev->quendu >= qcnt) {
582
                dev->quendu = 0;
583
        }
584
        /*
585
         *      Check queue state
586
         */
587
        if (dev->quhdu == dev->quendu) {
588
                if (dev->quendu == 0) {
589
                        dev->quendu = qcnt;
590
                }
591
                dev->quendu--;
592
                req_p->result = 0x00020000;
593
                done(req_p);
594
                restore_flags(flags);
595
                return 0;
596
        }
597
        dev->querequ[dev->quendu] = req_p;
598
        tmport = dev->ioport + 0x1c;
599
        restore_flags(flags);
600
        if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
601
                send_s870(h);
602
        }
603
        return 0;
604
}
605
 
606
void mydlyu(unsigned int dlycnt)
607
{
608
        unsigned int i;
609
        for (i = 0; i < dlycnt; i++) {
610
                inb(0x80);
611
        }
612
}
613
 
614
void send_s870(unsigned char h)
615
{
616
        unsigned int tmport;
617
        Scsi_Cmnd *workrequ;
618
        unsigned long flags;
619
        unsigned int i;
620
        unsigned char j, target_id;
621
        unsigned char *prd;
622
        unsigned short int tmpcip, w;
623
        unsigned long l, bttl;
624
        unsigned int workportu;
625
        struct scatterlist *sgpnt;
626
        struct atp_unit *dev = &atp_unit[h];
627
 
628
        save_flags(flags);
629
        cli();
630
        if (dev->in_snd != 0) {
631
                restore_flags(flags);
632
                return;
633
        }
634
        dev->in_snd = 1;
635
        if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
636
                dev->last_cmd &= 0x0f;
637
                workrequ = dev->id[dev->last_cmd].curr_req;
638
                if (workrequ != NULL)        /* check NULL pointer */
639
                {
640
                   goto cmd_subp;
641
                }
642
                dev->last_cmd = 0xff;
643
                if (dev->quhdu == dev->quendu)
644
                {
645
                   dev->in_snd = 0;
646
                   restore_flags(flags);
647
                   return ;
648
                }
649
        }
650
        if ((dev->last_cmd != 0xff) && (dev->working != 0))
651
        {
652
             dev->in_snd = 0;
653
             restore_flags(flags);
654
             return ;
655
        }
656
        dev->working++;
657
        j = dev->quhdu;
658
        dev->quhdu++;
659
        if (dev->quhdu >= qcnt) {
660
                dev->quhdu = 0;
661
        }
662
        workrequ = dev->querequ[dev->quhdu];
663
        if (dev->id[workrequ->target].curr_req == 0) {
664
                dev->id[workrequ->target].curr_req = workrequ;
665
                dev->last_cmd = workrequ->target;
666
                goto cmd_subp;
667
        }
668
        dev->quhdu = j;
669
        dev->working--;
670
        dev->in_snd = 0;
671
        restore_flags(flags);
672
        return;
673
cmd_subp:
674
        workportu = dev->ioport;
675
        tmport = workportu + 0x1f;
676
        if ((inb(tmport) & 0xb0) != 0) {
677
                goto abortsnd;
678
        }
679
        tmport = workportu + 0x1c;
680
        if (inb(tmport) == 0) {
681
                goto oktosend;
682
        }
683
abortsnd:
684
        dev->last_cmd |= 0x40;
685
        dev->in_snd = 0;
686
        restore_flags(flags);
687
        return;
688
oktosend:
689
        memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
690
        if (dev->ata_cdbu[0] == READ_CAPACITY) {
691
                if (workrequ->request_bufflen > 8) {
692
                        workrequ->request_bufflen = 0x08;
693
                }
694
        }
695
        if (dev->ata_cdbu[0] == 0x00) {
696
                workrequ->request_bufflen = 0;
697
        }
698
 
699
        tmport = workportu + 0x1b;
700
        j = 0;
701
        target_id = workrequ->target;
702
 
703
        /*
704
         *      Wide ?
705
         */
706
        w = 1;
707
        w = w << target_id;
708
        if ((w & dev->wide_idu) != 0) {
709
                j |= 0x01;
710
        }
711
        outb(j, tmport);
712
        while ((inb(tmport) & 0x01) != j)
713
        {
714
           outb(j,tmport);
715
        }
716
 
717
        /*
718
         *      Write the command
719
         */
720
 
721
        tmport = workportu;
722
        outb(workrequ->cmd_len, tmport++);
723
        outb(0x2c, tmport++);
724
        outb(0xcf, tmport++);
725
        for (i = 0; i < workrequ->cmd_len; i++) {
726
                outb(dev->ata_cdbu[i], tmport++);
727
        }
728
        tmport = workportu + 0x0f;
729
        outb(workrequ->lun, tmport);
730
        tmport += 0x02;
731
        /*
732
         *      Write the target
733
         */
734
        outb(dev->id[target_id].devspu, tmport++);
735
 
736
        /*
737
         *      Figure out the transfer size
738
         */
739
        if (workrequ->use_sg)
740
        {
741
                l = 0;
742
                sgpnt = (struct scatterlist *) workrequ->request_buffer;
743
                for (i = 0; i < workrequ->use_sg; i++)
744
                {
745
                        if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)
746
                        {
747
                                panic("Foooooooood fight!");
748
                        }
749
                        l += sgpnt[i].length;
750
                }
751
        } else {
752
                l = workrequ->request_bufflen;
753
        }
754
        /*
755
         *      Write transfer size
756
         */
757
        outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
758
        outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
759
        outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
760
        j = target_id;
761
        dev->id[j].last_lenu = l;
762
        dev->id[j].tran_lenu = 0;
763
        /*
764
         *      Flip the wide bits
765
         */
766
        if ((j & 0x08) != 0) {
767
                j = (j & 0x07) | 0x40;
768
        }
769
        /*
770
         *      Check transfer direction
771
         */
772
        if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
773
            (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT)) {
774
                outb((unsigned char) (j | 0x20), tmport++);
775
        } else {
776
                outb(j, tmport++);
777
        }
778
        outb((unsigned char)(inb(tmport) | 0x80),tmport);
779
        outb(0x80, tmport);
780
        tmport = workportu + 0x1c;
781
        dev->id[target_id].dirctu = 0;
782
        if (l == 0) {
783
                if (inb(tmport) == 0) {
784
                        tmport = workportu + 0x18;
785
                        outb(0x08, tmport);
786
                } else {
787
                        dev->last_cmd |= 0x40;
788
                }
789
                dev->in_snd = 0;
790
                restore_flags(flags);
791
                return;
792
        }
793
        tmpcip = dev->pciport;
794
        prd = dev->id[target_id].prd_tableu;
795
        dev->id[target_id].prd_posu = prd;
796
 
797
        /*
798
         *      Now write the request list. Either as scatter/gather or as
799
         *      a linear chain.
800
         */
801
 
802
        if (workrequ->use_sg)
803
        {
804
                sgpnt = (struct scatterlist *) workrequ->request_buffer;
805
                i = 0;
806
                for (j = 0; j < workrequ->use_sg; j++) {
807
                        bttl = virt_to_bus(sgpnt[j].address);
808
                        l = sgpnt[j].length;
809
                        while (l > 0x10000) {
810
                                (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;
811
                                (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;
812
                                (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
813
                                l -= 0x10000;
814
                                bttl += 0x10000;
815
                                i += 0x04;
816
                        }
817
                        (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
818
                        (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;
819
                        (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0;
820
                        i += 0x04;
821
                }
822
                (unsigned short int) (((unsigned short int *) (prd))[i - 1]) = 0x8000;
823
        } else {
824
                /*
825
                 *      For a linear request write a chain of blocks
826
                 */
827
                bttl = virt_to_bus(workrequ->request_buffer);
828
                l = workrequ->request_bufflen;
829
                i = 0;
830
                while (l > 0x10000) {
831
                        (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;
832
                        (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;
833
                        (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
834
                        l -= 0x10000;
835
                        bttl += 0x10000;
836
                        i += 0x04;
837
                }
838
                (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x8000;
839
                (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;
840
                (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
841
        }
842
        tmpcip = tmpcip + 4;
843
        dev->id[target_id].prdaddru = virt_to_bus(dev->id[target_id].prd_tableu);
844
        outl(dev->id[target_id].prdaddru, tmpcip);
845
        tmpcip = tmpcip - 2;
846
        outb(0x06, tmpcip);
847
        outb(0x00, tmpcip);
848
        tmpcip = tmpcip - 2;
849
 
850
        if (dev->deviceid != 0x8081)
851
        {
852
           tmport = workportu + 0x3a;
853
           if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
854
               (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
855
           {
856
              outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
857
           }
858
           else
859
           {
860
              outb((unsigned char)(inb(tmport) & 0xf3),tmport);
861
           }
862
        }
863
        else
864
        {
865
           tmport = workportu - 0x05;
866
           if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
867
               (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
868
           {
869
              outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
870
           }
871
           else
872
           {
873
              outb((unsigned char)(inb(tmport) & 0x3f),tmport);
874
           }
875
        }
876
        tmport = workportu + 0x1c;
877
 
878
        if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
879
            (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT))
880
        {
881
                dev->id[target_id].dirctu = 0x20;
882
                if (inb(tmport) == 0) {
883
                        tmport = workportu + 0x18;
884
                        outb(0x08, tmport);
885
                        outb(0x01, tmpcip);
886
                } else {
887
                        dev->last_cmd |= 0x40;
888
                }
889
                dev->in_snd = 0;
890
                restore_flags(flags);
891
                return;
892
        }
893
        if (inb(tmport) == 0)
894
        {
895
                tmport = workportu + 0x18;
896
                outb(0x08, tmport);
897
                outb(0x09, tmpcip);
898
        } else {
899
                dev->last_cmd |= 0x40;
900
        }
901
        dev->in_snd = 0;
902
        restore_flags(flags);
903
        return;
904
 
905
}
906
 
907
static void internal_done(Scsi_Cmnd * SCpnt)
908
{
909
        SCpnt->SCp.Status++;
910
}
911
 
912
int atp870u_command(Scsi_Cmnd * SCpnt)
913
{
914
 
915
        atp870u_queuecommand(SCpnt, internal_done);
916
 
917
        SCpnt->SCp.Status = 0;
918
        while (!SCpnt->SCp.Status)
919
                barrier();
920
        return SCpnt->result;
921
}
922
 
923
unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
924
{
925
        unsigned int tmport;
926
        unsigned short int i, k;
927
        unsigned char j;
928
 
929
        tmport = dev->ioport + 0x1c;
930
        outw(*val, tmport);
931
FUN_D7:
932
        for (i = 0; i < 10; i++) {       /* stable >= bus settle delay(400 ns)  */
933
                k = inw(tmport);
934
                j = (unsigned char) (k >> 8);
935
                if ((k & 0x8000) != 0) { /* DB7 all release?    */
936
                        goto FUN_D7;
937
                }
938
        }
939
        *val |= 0x4000;         /* assert DB6           */
940
        outw(*val, tmport);
941
        *val &= 0xdfff;         /* assert DB5           */
942
        outw(*val, tmport);
943
FUN_D5:
944
        for (i = 0; i < 10; i++) {       /* stable >= bus settle delay(400 ns) */
945
                if ((inw(tmport) & 0x2000) != 0) {       /* DB5 all release?       */
946
                        goto FUN_D5;
947
                }
948
        }
949
        *val |= 0x8000;         /* no DB4-0, assert DB7    */
950
        *val &= 0xe0ff;
951
        outw(*val, tmport);
952
        *val &= 0xbfff;         /* release DB6             */
953
        outw(*val, tmport);
954
      FUN_D6:
955
        for (i = 0; i < 10; i++) {       /* stable >= bus settle delay(400 ns)  */
956
                if ((inw(tmport) & 0x4000) != 0) {       /* DB6 all release?  */
957
                        goto FUN_D6;
958
                }
959
        }
960
 
961
        return j;
962
}
963
 
964
void tscam(unsigned char host)
965
{
966
 
967
        unsigned int tmport;
968
        unsigned char i, j, k;
969
        unsigned long n;
970
        unsigned short int m, assignid_map, val;
971
        unsigned char mbuf[33], quintet[2];
972
        struct atp_unit *dev = &atp_unit[host];
973
        static unsigned char g2q_tab[8] = {
974
                0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
975
        };
976
 
977
 
978
        for (i = 0; i < 0x10; i++) {
979
                mydlyu(0xffff);
980
        }
981
 
982
        tmport = dev->ioport + 1;
983
        outb(0x08, tmport++);
984
        outb(0x7f, tmport);
985
        tmport = dev->ioport + 0x11;
986
        outb(0x20, tmport);
987
 
988
        if ((dev->scam_on & 0x40) == 0) {
989
                return;
990
        }
991
        m = 1;
992
        m <<= dev->host_idu;
993
        j = 16;
994
        if (dev->chip_veru < 4) {
995
                m |= 0xff00;
996
                j = 8;
997
        }
998
        assignid_map = m;
999
        tmport = dev->ioport + 0x02;
1000
        outb(0x02, tmport++);   /* 2*2=4ms,3EH 2/32*3E=3.9ms */
1001
        outb(0, tmport++);
1002
        outb(0, tmport++);
1003
        outb(0, tmport++);
1004
        outb(0, tmport++);
1005
        outb(0, tmport++);
1006
        outb(0, tmport++);
1007
 
1008
        for (i = 0; i < j; i++) {
1009
                m = 1;
1010
                m = m << i;
1011
                if ((m & assignid_map) != 0) {
1012
                        continue;
1013
                }
1014
                tmport = dev->ioport + 0x0f;
1015
                outb(0, tmport++);
1016
                tmport += 0x02;
1017
                outb(0, tmport++);
1018
                outb(0, tmport++);
1019
                outb(0, tmport++);
1020
                if (i > 7) {
1021
                        k = (i & 0x07) | 0x40;
1022
                } else {
1023
                        k = i;
1024
                }
1025
                outb(k, tmport++);
1026
                tmport = dev->ioport + 0x1b;
1027
                if (dev->chip_veru == 4) {
1028
                        outb(0x01, tmport);
1029
                } else {
1030
                        outb(0x00, tmport);
1031
                }
1032
wait_rdyok:
1033
                tmport = dev->ioport + 0x18;
1034
                outb(0x09, tmport);
1035
                tmport += 0x07;
1036
 
1037
                while ((inb(tmport) & 0x80) == 0x00);
1038
                tmport -= 0x08;
1039
                k = inb(tmport);
1040
                if (k != 0x16) {
1041
                        if ((k == 0x85) || (k == 0x42)) {
1042
                                continue;
1043
                        }
1044
                        tmport = dev->ioport + 0x10;
1045
                        outb(0x41, tmport);
1046
                        goto wait_rdyok;
1047
                }
1048
                assignid_map |= m;
1049
 
1050
        }
1051
        tmport = dev->ioport + 0x02;
1052
        outb(0x7f, tmport);
1053
        tmport = dev->ioport + 0x1b;
1054
        outb(0x02, tmport);
1055
 
1056
        outb(0, 0x80);
1057
 
1058
        val = 0x0080;           /* bsy  */
1059
        tmport = dev->ioport + 0x1c;
1060
        outw(val, tmport);
1061
        val |= 0x0040;          /* sel  */
1062
        outw(val, tmport);
1063
        val |= 0x0004;          /* msg  */
1064
        outw(val, tmport);
1065
        inb(0x80);              /* 2 deskew delay(45ns*2=90ns) */
1066
        val &= 0x007f;          /* no bsy  */
1067
        outw(val, tmport);
1068
        mydlyu(0xffff);         /* recommanded SCAM selection response time */
1069
        mydlyu(0xffff);
1070
        val &= 0x00fb;          /* after 1ms no msg */
1071
        outw(val, tmport);
1072
wait_nomsg:
1073
        if ((inb(tmport) & 0x04) != 0) {
1074
                goto wait_nomsg;
1075
        }
1076
        outb(1, 0x80);
1077
        mydlyu(100);
1078
        for (n = 0; n < 0x30000; n++) {
1079
                if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
1080
                        goto wait_io;
1081
                }
1082
        }
1083
        goto TCM_SYNC;
1084
wait_io:
1085
        for (n = 0; n < 0x30000; n++) {
1086
                if ((inb(tmport) & 0x81) == 0x0081) {
1087
                        goto wait_io1;
1088
                }
1089
        }
1090
        goto TCM_SYNC;
1091
wait_io1:
1092
        inb(0x80);
1093
        val |= 0x8003;          /* io,cd,db7  */
1094
        outw(val, tmport);
1095
        inb(0x80);
1096
        val &= 0x00bf;          /* no sel     */
1097
        outw(val, tmport);
1098
        outb(2, 0x80);
1099
TCM_SYNC:
1100
        mydlyu(0x800);
1101
        if ((inb(tmport) & 0x80) == 0x00) {     /* bsy ? */
1102
                outw(0, tmport--);
1103
                outb(0, tmport);
1104
                tmport = dev->ioport + 0x15;
1105
                outb(0, tmport);
1106
                tmport += 0x03;
1107
                outb(0x09, tmport);
1108
                tmport += 0x07;
1109
                while ((inb(tmport) & 0x80) == 0);
1110
                tmport -= 0x08;
1111
                inb(tmport);
1112
                return;
1113
        }
1114
        val &= 0x00ff;          /* synchronization  */
1115
        val |= 0x3f00;
1116
        fun_scam(dev, &val);
1117
        outb(3, 0x80);
1118
        val &= 0x00ff;          /* isolation        */
1119
        val |= 0x2000;
1120
        fun_scam(dev, &val);
1121
        outb(4, 0x80);
1122
        i = 8;
1123
        j = 0;
1124
TCM_ID:
1125
        if ((inw(tmport) & 0x2000) == 0) {
1126
                goto TCM_ID;
1127
        }
1128
        outb(5, 0x80);
1129
        val &= 0x00ff;          /* get ID_STRING */
1130
        val |= 0x2000;
1131
        k = fun_scam(dev, &val);
1132
        if ((k & 0x03) == 0) {
1133
                goto TCM_5;
1134
        }
1135
        mbuf[j] <<= 0x01;
1136
        mbuf[j] &= 0xfe;
1137
        if ((k & 0x02) != 0) {
1138
                mbuf[j] |= 0x01;
1139
        }
1140
        i--;
1141
        if (i > 0) {
1142
                goto TCM_ID;
1143
        }
1144
        j++;
1145
        i = 8;
1146
        goto TCM_ID;
1147
 
1148
TCM_5:                  /* isolation complete..  */
1149
/*    mbuf[32]=0;
1150
        printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1151
        i = 15;
1152
        j = mbuf[0];
1153
        if ((j & 0x20) != 0) {   /* bit5=1:ID upto 7      */
1154
                i = 7;
1155
        }
1156
        if ((j & 0x06) == 0) {   /* IDvalid?             */
1157
                goto G2Q5;
1158
        }
1159
        k = mbuf[1];
1160
small_id:
1161
        m = 1;
1162
        m <<= k;
1163
        if ((m & assignid_map) == 0) {
1164
                goto G2Q_QUIN;
1165
        }
1166
        if (k > 0) {
1167
                k--;
1168
                goto small_id;
1169
        }
1170
G2Q5:                           /* srch from max acceptable ID#  */
1171
        k = i;                  /* max acceptable ID#            */
1172
G2Q_LP:
1173
        m = 1;
1174
        m <<= k;
1175
        if ((m & assignid_map) == 0) {
1176
                goto G2Q_QUIN;
1177
        }
1178
        if (k > 0) {
1179
                k--;
1180
                goto G2Q_LP;
1181
        }
1182
G2Q_QUIN:               /* k=binID#,       */
1183
        assignid_map |= m;
1184
        if (k < 8) {
1185
                quintet[0] = 0x38;       /* 1st dft ID<8    */
1186
        } else {
1187
                quintet[0] = 0x31;       /* 1st  ID>=8      */
1188
        }
1189
        k &= 0x07;
1190
        quintet[1] = g2q_tab[k];
1191
 
1192
        val &= 0x00ff;          /* AssignID 1stQuintet,AH=001xxxxx  */
1193
        m = quintet[0] << 8;
1194
        val |= m;
1195
        fun_scam(dev, &val);
1196
        val &= 0x00ff;          /* AssignID 2ndQuintet,AH=001xxxxx */
1197
        m = quintet[1] << 8;
1198
        val |= m;
1199
        fun_scam(dev, &val);
1200
 
1201
        goto TCM_SYNC;
1202
 
1203
}
1204
 
1205
void is870(unsigned long host, unsigned int wkport)
1206
{
1207
        unsigned int tmport;
1208
        unsigned char i, j, k, rmb, n;
1209
        unsigned short int m;
1210
        static unsigned char mbuf[512];
1211
        static unsigned char satn[9] =  {0, 0, 0, 0, 0, 0, 0, 6, 6};
1212
        static unsigned char inqd[9] =  {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1213
        static unsigned char synn[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
1214
        static unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0c, 0x0e};
1215
        static unsigned char synw[6] =  {0x80, 1, 3, 1, 0x0c, 0x07};
1216
        static unsigned char wide[6] =  {0x80, 1, 2, 3, 1, 0};
1217
        struct atp_unit *dev = &atp_unit[host];
1218
 
1219
        sync_idu = 0;
1220
        tmport = wkport + 0x3a;
1221
        outb((unsigned char) (inb(tmport) | 0x10), tmport);
1222
 
1223
        for (i = 0; i < 16; i++) {
1224
                if ((dev->chip_veru != 4) && (i > 7)) {
1225
                        break;
1226
                }
1227
                m = 1;
1228
                m = m << i;
1229
                if ((m & dev->active_idu) != 0) {
1230
                        continue;
1231
                }
1232
                if (i == dev->host_idu) {
1233
                        printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);
1234
                        continue;
1235
                }
1236
                tmport = wkport + 0x1b;
1237
                if (dev->chip_veru == 4) {
1238
                   outb(0x01, tmport);
1239
                }
1240
                else
1241
                {
1242
                   outb(0x00, tmport);
1243
                }
1244
                tmport = wkport + 1;
1245
                outb(0x08, tmport++);
1246
                outb(0x7f, tmport++);
1247
                outb(satn[0], tmport++);
1248
                outb(satn[1], tmport++);
1249
                outb(satn[2], tmport++);
1250
                outb(satn[3], tmport++);
1251
                outb(satn[4], tmport++);
1252
                outb(satn[5], tmport++);
1253
                tmport += 0x06;
1254
                outb(0, tmport);
1255
                tmport += 0x02;
1256
                outb(dev->id[i].devspu, tmport++);
1257
                outb(0, tmport++);
1258
                outb(satn[6], tmport++);
1259
                outb(satn[7], tmport++);
1260
                j = i;
1261
                if ((j & 0x08) != 0) {
1262
                        j = (j & 0x07) | 0x40;
1263
                }
1264
                outb(j, tmport);
1265
                tmport += 0x03;
1266
                outb(satn[8], tmport);
1267
                tmport += 0x07;
1268
 
1269
                while ((inb(tmport) & 0x80) == 0x00);
1270
                tmport -= 0x08;
1271
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1272
                        continue;
1273
                }
1274
                while (inb(tmport) != 0x8e);
1275
                dev->active_idu |= m;
1276
 
1277
                tmport = wkport + 0x10;
1278
                outb(0x30, tmport);
1279
                tmport = wkport + 0x04;
1280
                outb(0x00, tmport);
1281
 
1282
phase_cmd:
1283
                tmport = wkport + 0x18;
1284
                outb(0x08, tmport);
1285
                tmport += 0x07;
1286
                while ((inb(tmport) & 0x80) == 0x00);
1287
                tmport -= 0x08;
1288
                j = inb(tmport);
1289
                if (j != 0x16) {
1290
                        tmport = wkport + 0x10;
1291
                        outb(0x41, tmport);
1292
                        goto phase_cmd;
1293
                }
1294
sel_ok:
1295
                tmport = wkport + 3;
1296
                outb(inqd[0], tmport++);
1297
                outb(inqd[1], tmport++);
1298
                outb(inqd[2], tmport++);
1299
                outb(inqd[3], tmport++);
1300
                outb(inqd[4], tmport++);
1301
                outb(inqd[5], tmport);
1302
                tmport += 0x07;
1303
                outb(0, tmport);
1304
                tmport += 0x02;
1305
                outb(dev->id[i].devspu, tmport++);
1306
                outb(0, tmport++);
1307
                outb(inqd[6], tmport++);
1308
                outb(inqd[7], tmport++);
1309
                tmport += 0x03;
1310
                outb(inqd[8], tmport);
1311
                tmport += 0x07;
1312
                while ((inb(tmport) & 0x80) == 0x00);
1313
                tmport -= 0x08;
1314
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1315
                        continue;
1316
                }
1317
                while (inb(tmport) != 0x8e);
1318
                tmport = wkport + 0x1b;
1319
                if (dev->chip_veru == 4) {
1320
                        outb(0x00, tmport);
1321
                }
1322
                tmport = wkport + 0x18;
1323
                outb(0x08, tmport);
1324
                tmport += 0x07;
1325
                j = 0;
1326
rd_inq_data:
1327
                k = inb(tmport);
1328
                if ((k & 0x01) != 0) {
1329
                        tmport -= 0x06;
1330
                        mbuf[j++] = inb(tmport);
1331
                        tmport += 0x06;
1332
                        goto rd_inq_data;
1333
                }
1334
                if ((k & 0x80) == 0) {
1335
                        goto rd_inq_data;
1336
                }
1337
                tmport -= 0x08;
1338
                j = inb(tmport);
1339
                if (j == 0x16) {
1340
                        goto inq_ok;
1341
                }
1342
                tmport = wkport + 0x10;
1343
                outb(0x46, tmport);
1344
                tmport += 0x02;
1345
                outb(0, tmport++);
1346
                outb(0, tmport++);
1347
                outb(0, tmport++);
1348
                tmport += 0x03;
1349
                outb(0x08, tmport);
1350
                tmport += 0x07;
1351
                while ((inb(tmport) & 0x80) == 0x00);
1352
                tmport -= 0x08;
1353
                if (inb(tmport) != 0x16) {
1354
                        goto sel_ok;
1355
                }
1356
inq_ok:
1357
                mbuf[36] = 0;
1358
                printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1359
                dev->id[i].devtypeu = mbuf[0];
1360
                rmb = mbuf[1];
1361
                n = mbuf[7];
1362
                if (dev->chip_veru != 4) {
1363
                        goto not_wide;
1364
                }
1365
                if ((mbuf[7] & 0x60) == 0) {
1366
                        goto not_wide;
1367
                }
1368
                if ((dev->global_map & 0x20) == 0) {
1369
                        goto not_wide;
1370
                }
1371
                tmport = wkport + 0x1b;
1372
                outb(0x01, tmport);
1373
                tmport = wkport + 3;
1374
                outb(satn[0], tmport++);
1375
                outb(satn[1], tmport++);
1376
                outb(satn[2], tmport++);
1377
                outb(satn[3], tmport++);
1378
                outb(satn[4], tmport++);
1379
                outb(satn[5], tmport++);
1380
                tmport += 0x06;
1381
                outb(0, tmport);
1382
                tmport += 0x02;
1383
                outb(dev->id[i].devspu, tmport++);
1384
                outb(0, tmport++);
1385
                outb(satn[6], tmport++);
1386
                outb(satn[7], tmport++);
1387
                tmport += 0x03;
1388
                outb(satn[8], tmport);
1389
                tmport += 0x07;
1390
 
1391
                while ((inb(tmport) & 0x80) == 0x00);
1392
                tmport -= 0x08;
1393
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1394
                        continue;
1395
                }
1396
                while (inb(tmport) != 0x8e);
1397
try_wide:
1398
                j = 0;
1399
                tmport = wkport + 0x14;
1400
                outb(0x05, tmport);
1401
                tmport += 0x04;
1402
                outb(0x20, tmport);
1403
                tmport += 0x07;
1404
 
1405
                while ((inb(tmport) & 0x80) == 0) {
1406
                        if ((inb(tmport) & 0x01) != 0) {
1407
                                tmport -= 0x06;
1408
                                outb(wide[j++], tmport);
1409
                                tmport += 0x06;
1410
                        }
1411
                }
1412
                tmport -= 0x08;
1413
                while ((inb(tmport) & 0x80) == 0x00);
1414
                j = inb(tmport) & 0x0f;
1415
                if (j == 0x0f) {
1416
                        goto widep_in;
1417
                }
1418
                if (j == 0x0a) {
1419
                        goto widep_cmd;
1420
                }
1421
                if (j == 0x0e) {
1422
                        goto try_wide;
1423
                }
1424
                continue;
1425
widep_out:
1426
                tmport = wkport + 0x18;
1427
                outb(0x20, tmport);
1428
                tmport += 0x07;
1429
                while ((inb(tmport) & 0x80) == 0) {
1430
                        if ((inb(tmport) & 0x01) != 0) {
1431
                                tmport -= 0x06;
1432
                                outb(0, tmport);
1433
                                tmport += 0x06;
1434
                        }
1435
                }
1436
                tmport -= 0x08;
1437
                j = inb(tmport) & 0x0f;
1438
                if (j == 0x0f) {
1439
                        goto widep_in;
1440
                }
1441
                if (j == 0x0a) {
1442
                        goto widep_cmd;
1443
                }
1444
                if (j == 0x0e) {
1445
                        goto widep_out;
1446
                }
1447
                continue;
1448
widep_in:
1449
                tmport = wkport + 0x14;
1450
                outb(0xff, tmport);
1451
                tmport += 0x04;
1452
                outb(0x20, tmport);
1453
                tmport += 0x07;
1454
                k = 0;
1455
widep_in1:
1456
                j = inb(tmport);
1457
                if ((j & 0x01) != 0) {
1458
                        tmport -= 0x06;
1459
                        mbuf[k++] = inb(tmport);
1460
                        tmport += 0x06;
1461
                        goto widep_in1;
1462
                }
1463
                if ((j & 0x80) == 0x00) {
1464
                        goto widep_in1;
1465
                }
1466
                tmport -= 0x08;
1467
                j = inb(tmport) & 0x0f;
1468
                if (j == 0x0f) {
1469
                        goto widep_in;
1470
                }
1471
                if (j == 0x0a) {
1472
                        goto widep_cmd;
1473
                }
1474
                if (j == 0x0e) {
1475
                        goto widep_out;
1476
                }
1477
                continue;
1478
widep_cmd:
1479
                tmport = wkport + 0x10;
1480
                outb(0x30, tmport);
1481
                tmport = wkport + 0x14;
1482
                outb(0x00, tmport);
1483
                tmport += 0x04;
1484
                outb(0x08, tmport);
1485
                tmport += 0x07;
1486
                while ((inb(tmport) & 0x80) == 0x00);
1487
                tmport -= 0x08;
1488
                j = inb(tmport);
1489
                if (j != 0x16) {
1490
                        if (j == 0x4e) {
1491
                                goto widep_out;
1492
                        }
1493
                        continue;
1494
                }
1495
                if (mbuf[0] != 0x01) {
1496
                        goto not_wide;
1497
                }
1498
                if (mbuf[1] != 0x02) {
1499
                        goto not_wide;
1500
                }
1501
                if (mbuf[2] != 0x03) {
1502
                        goto not_wide;
1503
                }
1504
                if (mbuf[3] != 0x01) {
1505
                        goto not_wide;
1506
                }
1507
                m = 1;
1508
                m = m << i;
1509
                dev->wide_idu |= m;
1510
not_wide:
1511
                if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
1512
                    ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
1513
                {
1514
                        goto set_sync;
1515
                }
1516
                continue;
1517
set_sync:
1518
                tmport = wkport + 0x1b;
1519
                j = 0;
1520
                if ((m & dev->wide_idu) != 0) {
1521
                        j |= 0x01;
1522
                }
1523
                outb(j, tmport);
1524
                tmport = wkport + 3;
1525
                outb(satn[0], tmport++);
1526
                outb(satn[1], tmport++);
1527
                outb(satn[2], tmport++);
1528
                outb(satn[3], tmport++);
1529
                outb(satn[4], tmport++);
1530
                outb(satn[5], tmport++);
1531
                tmport += 0x06;
1532
                outb(0, tmport);
1533
                tmport += 0x02;
1534
                outb(dev->id[i].devspu, tmport++);
1535
                outb(0, tmport++);
1536
                outb(satn[6], tmport++);
1537
                outb(satn[7], tmport++);
1538
                tmport += 0x03;
1539
                outb(satn[8], tmport);
1540
                tmport += 0x07;
1541
 
1542
                while ((inb(tmport) & 0x80) == 0x00);
1543
                tmport -= 0x08;
1544
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1545
                        continue;
1546
                }
1547
                while (inb(tmport) != 0x8e);
1548
try_sync:
1549
                j = 0;
1550
                tmport = wkport + 0x14;
1551
                outb(0x06, tmport);
1552
                tmport += 0x04;
1553
                outb(0x20, tmport);
1554
                tmport += 0x07;
1555
 
1556
                while ((inb(tmport) & 0x80) == 0) {
1557
                        if ((inb(tmport) & 0x01) != 0) {
1558
                                tmport -= 0x06;
1559
                                if ((m & dev->wide_idu) != 0) {
1560
                                        outb(synw[j++], tmport);
1561
                                } else {
1562
                                        if ((m & dev->ultra_map) != 0) {
1563
                                                outb(synu[j++], tmport);
1564
                                        } else {
1565
                                                outb(synn[j++], tmport);
1566
                                        }
1567
                                }
1568
                                tmport += 0x06;
1569
                        }
1570
                }
1571
                tmport -= 0x08;
1572
                while ((inb(tmport) & 0x80) == 0x00);
1573
                j = inb(tmport) & 0x0f;
1574
                if (j == 0x0f) {
1575
                        goto phase_ins;
1576
                }
1577
                if (j == 0x0a) {
1578
                        goto phase_cmds;
1579
                }
1580
                if (j == 0x0e) {
1581
                        goto try_sync;
1582
                }
1583
                continue;
1584
phase_outs:
1585
                tmport = wkport + 0x18;
1586
                outb(0x20, tmport);
1587
                tmport += 0x07;
1588
                while ((inb(tmport) & 0x80) == 0x00) {
1589
                        if ((inb(tmport) & 0x01) != 0x00) {
1590
                                tmport -= 0x06;
1591
                                outb(0x00, tmport);
1592
                                tmport += 0x06;
1593
                        }
1594
                }
1595
                tmport -= 0x08;
1596
                j = inb(tmport);
1597
                if (j == 0x85) {
1598
                        goto tar_dcons;
1599
                }
1600
                j &= 0x0f;
1601
                if (j == 0x0f) {
1602
                        goto phase_ins;
1603
                }
1604
                if (j == 0x0a) {
1605
                        goto phase_cmds;
1606
                }
1607
                if (j == 0x0e) {
1608
                        goto phase_outs;
1609
                }
1610
                continue;
1611
phase_ins:
1612
                tmport = wkport + 0x14;
1613
                outb(0xff, tmport);
1614
                tmport += 0x04;
1615
                outb(0x20, tmport);
1616
                tmport += 0x07;
1617
                k = 0;
1618
phase_ins1:
1619
                j = inb(tmport);
1620
                if ((j & 0x01) != 0x00) {
1621
                        tmport -= 0x06;
1622
                        mbuf[k++] = inb(tmport);
1623
                        tmport += 0x06;
1624
                        goto phase_ins1;
1625
                }
1626
                if ((j & 0x80) == 0x00) {
1627
                        goto phase_ins1;
1628
                }
1629
                tmport -= 0x08;
1630
                while ((inb(tmport) & 0x80) == 0x00);
1631
                j = inb(tmport);
1632
                if (j == 0x85) {
1633
                        goto tar_dcons;
1634
                }
1635
                j &= 0x0f;
1636
                if (j == 0x0f) {
1637
                        goto phase_ins;
1638
                }
1639
                if (j == 0x0a) {
1640
                        goto phase_cmds;
1641
                }
1642
                if (j == 0x0e) {
1643
                        goto phase_outs;
1644
                }
1645
                continue;
1646
phase_cmds:
1647
                tmport = wkport + 0x10;
1648
                outb(0x30, tmport);
1649
tar_dcons:
1650
                tmport = wkport + 0x14;
1651
                outb(0x00, tmport);
1652
                tmport += 0x04;
1653
                outb(0x08, tmport);
1654
                tmport += 0x07;
1655
                while ((inb(tmport) & 0x80) == 0x00);
1656
                tmport -= 0x08;
1657
                j = inb(tmport);
1658
                if (j != 0x16) {
1659
                        continue;
1660
                }
1661
                if (mbuf[0] != 0x01) {
1662
                        continue;
1663
                }
1664
                if (mbuf[1] != 0x03) {
1665
                        continue;
1666
                }
1667
                if (mbuf[4] == 0x00) {
1668
                        continue;
1669
                }
1670
                if (mbuf[3] > 0x64) {
1671
                        continue;
1672
                }
1673
                if (mbuf[4] > 0x0c) {
1674
                        mbuf[4] = 0x0c;
1675
                }
1676
                dev->id[i].devspu = mbuf[4];
1677
                if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1678
                        j = 0xa0;
1679
                        goto set_syn_ok;
1680
                }
1681
                if (mbuf[3] < 0x1a) {
1682
                        j = 0x20;
1683
                        goto set_syn_ok;
1684
                }
1685
                if (mbuf[3] < 0x33) {
1686
                        j = 0x40;
1687
                        goto set_syn_ok;
1688
                }
1689
                if (mbuf[3] < 0x4c) {
1690
                        j = 0x50;
1691
                        goto set_syn_ok;
1692
                }
1693
                j = 0x60;
1694
              set_syn_ok:
1695
                dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
1696
        }
1697
        tmport = wkport + 0x3a;
1698
        outb((unsigned char) (inb(tmport) & 0xef), tmport);
1699
}
1700
 
1701
void is880(unsigned long host, unsigned int wkport)
1702
{
1703
        unsigned int tmport;
1704
        unsigned char i, j, k, rmb, n, lvdmode;
1705
        unsigned short int m;
1706
        static unsigned char mbuf[512];
1707
        static unsigned char satn[9] =  {0, 0, 0, 0, 0, 0, 0, 6, 6};
1708
        static unsigned char inqd[9] =  {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
1709
        static unsigned char synn[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
1710
        unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
1711
        static unsigned char synw[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
1712
        unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
1713
        static unsigned char wide[6] =  {0x80, 1, 2, 3, 1, 0};
1714
        static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
1715
        struct atp_unit *dev = &atp_unit[host];
1716
 
1717
        sync_idu = 0;
1718
        lvdmode=inb(wkport + 0x3f) & 0x40;
1719
 
1720
        for (i = 0; i < 16; i++) {
1721
                m = 1;
1722
                m = m << i;
1723
                if ((m & dev->active_idu) != 0) {
1724
                        continue;
1725
                }
1726
                if (i == dev->host_idu) {
1727
                        printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_idu);
1728
                        continue;
1729
                }
1730
                tmport = wkport + 0x5b;
1731
                outb(0x01, tmport);
1732
                tmport = wkport + 0x41;
1733
                outb(0x08, tmport++);
1734
                outb(0x7f, tmport++);
1735
                outb(satn[0], tmport++);
1736
                outb(satn[1], tmport++);
1737
                outb(satn[2], tmport++);
1738
                outb(satn[3], tmport++);
1739
                outb(satn[4], tmport++);
1740
                outb(satn[5], tmport++);
1741
                tmport += 0x06;
1742
                outb(0, tmport);
1743
                tmport += 0x02;
1744
                outb(dev->id[i].devspu, tmport++);
1745
                outb(0, tmport++);
1746
                outb(satn[6], tmport++);
1747
                outb(satn[7], tmport++);
1748
                j = i;
1749
                if ((j & 0x08) != 0) {
1750
                        j = (j & 0x07) | 0x40;
1751
                }
1752
                outb(j, tmport);
1753
                tmport += 0x03;
1754
                outb(satn[8], tmport);
1755
                tmport += 0x07;
1756
 
1757
                while ((inb(tmport) & 0x80) == 0x00);
1758
                tmport -= 0x08;
1759
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1760
                        continue;
1761
                }
1762
                while (inb(tmport) != 0x8e);
1763
                dev->active_idu |= m;
1764
 
1765
                tmport = wkport + 0x50;
1766
                outb(0x30, tmport);
1767
                tmport = wkport + 0x54;
1768
                outb(0x00, tmport);
1769
 
1770
phase_cmd:
1771
                tmport = wkport + 0x58;
1772
                outb(0x08, tmport);
1773
                tmport += 0x07;
1774
                while ((inb(tmport) & 0x80) == 0x00);
1775
                tmport -= 0x08;
1776
                j = inb(tmport);
1777
                if (j != 0x16) {
1778
                        tmport = wkport + 0x50;
1779
                        outb(0x41, tmport);
1780
                        goto phase_cmd;
1781
                }
1782
sel_ok:
1783
                tmport = wkport + 0x43;
1784
                outb(inqd[0], tmport++);
1785
                outb(inqd[1], tmport++);
1786
                outb(inqd[2], tmport++);
1787
                outb(inqd[3], tmport++);
1788
                outb(inqd[4], tmport++);
1789
                outb(inqd[5], tmport);
1790
                tmport += 0x07;
1791
                outb(0, tmport);
1792
                tmport += 0x02;
1793
                outb(dev->id[i].devspu, tmport++);
1794
                outb(0, tmport++);
1795
                outb(inqd[6], tmport++);
1796
                outb(inqd[7], tmport++);
1797
                tmport += 0x03;
1798
                outb(inqd[8], tmport);
1799
                tmport += 0x07;
1800
                while ((inb(tmport) & 0x80) == 0x00);
1801
                tmport -= 0x08;
1802
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1803
                        continue;
1804
                }
1805
                while (inb(tmport) != 0x8e);
1806
                tmport = wkport + 0x5b;
1807
                outb(0x00, tmport);
1808
                tmport = wkport + 0x58;
1809
                outb(0x08, tmport);
1810
                tmport += 0x07;
1811
                j = 0;
1812
rd_inq_data:
1813
                k = inb(tmport);
1814
                if ((k & 0x01) != 0) {
1815
                        tmport -= 0x06;
1816
                        mbuf[j++] = inb(tmport);
1817
                        tmport += 0x06;
1818
                        goto rd_inq_data;
1819
                }
1820
                if ((k & 0x80) == 0) {
1821
                        goto rd_inq_data;
1822
                }
1823
                tmport -= 0x08;
1824
                j = inb(tmport);
1825
                if (j == 0x16) {
1826
                        goto inq_ok;
1827
                }
1828
                tmport = wkport + 0x50;
1829
                outb(0x46, tmport);
1830
                tmport += 0x02;
1831
                outb(0, tmport++);
1832
                outb(0, tmport++);
1833
                outb(0, tmport++);
1834
                tmport += 0x03;
1835
                outb(0x08, tmport);
1836
                tmport += 0x07;
1837
                while ((inb(tmport) & 0x80) == 0x00);
1838
                tmport -= 0x08;
1839
                if (inb(tmport) != 0x16) {
1840
                        goto sel_ok;
1841
                }
1842
inq_ok:
1843
                mbuf[36] = 0;
1844
                printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1845
                dev->id[i].devtypeu = mbuf[0];
1846
                rmb = mbuf[1];
1847
                n = mbuf[7];
1848
                if ((mbuf[7] & 0x60) == 0) {
1849
                        goto not_wide;
1850
                }
1851
                if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
1852
                        goto not_wide;
1853
                }
1854
                if (lvdmode == 0)
1855
                {
1856
                   goto chg_wide;
1857
                }
1858
                if (dev->sp[i] != 0x04)          // force u2
1859
                {
1860
                   goto chg_wide;
1861
                }
1862
 
1863
                tmport = wkport + 0x5b;
1864
                outb(0x01, tmport);
1865
                tmport = wkport + 0x43;
1866
                outb(satn[0], tmport++);
1867
                outb(satn[1], tmport++);
1868
                outb(satn[2], tmport++);
1869
                outb(satn[3], tmport++);
1870
                outb(satn[4], tmport++);
1871
                outb(satn[5], tmport++);
1872
                tmport += 0x06;
1873
                outb(0, tmport);
1874
                tmport += 0x02;
1875
                outb(dev->id[i].devspu, tmport++);
1876
                outb(0, tmport++);
1877
                outb(satn[6], tmport++);
1878
                outb(satn[7], tmport++);
1879
                tmport += 0x03;
1880
                outb(satn[8], tmport);
1881
                tmport += 0x07;
1882
 
1883
                while ((inb(tmport) & 0x80) == 0x00);
1884
                tmport -= 0x08;
1885
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
1886
                        continue;
1887
                }
1888
                while (inb(tmport) != 0x8e);
1889
try_u3:
1890
                j = 0;
1891
                tmport = wkport + 0x54;
1892
                outb(0x09, tmport);
1893
                tmport += 0x04;
1894
                outb(0x20, tmport);
1895
                tmport += 0x07;
1896
 
1897
                while ((inb(tmport) & 0x80) == 0) {
1898
                        if ((inb(tmport) & 0x01) != 0) {
1899
                                tmport -= 0x06;
1900
                                outb(u3[j++], tmport);
1901
                                tmport += 0x06;
1902
                        }
1903
                }
1904
                tmport -= 0x08;
1905
                while ((inb(tmport) & 0x80) == 0x00);
1906
                j = inb(tmport) & 0x0f;
1907
                if (j == 0x0f) {
1908
                        goto u3p_in;
1909
                }
1910
                if (j == 0x0a) {
1911
                        goto u3p_cmd;
1912
                }
1913
                if (j == 0x0e) {
1914
                        goto try_u3;
1915
                }
1916
                continue;
1917
u3p_out:
1918
                tmport = wkport + 0x58;
1919
                outb(0x20, tmport);
1920
                tmport += 0x07;
1921
                while ((inb(tmport) & 0x80) == 0) {
1922
                        if ((inb(tmport) & 0x01) != 0) {
1923
                                tmport -= 0x06;
1924
                                outb(0, tmport);
1925
                                tmport += 0x06;
1926
                        }
1927
                }
1928
                tmport -= 0x08;
1929
                j = inb(tmport) & 0x0f;
1930
                if (j == 0x0f) {
1931
                        goto u3p_in;
1932
                }
1933
                if (j == 0x0a) {
1934
                        goto u3p_cmd;
1935
                }
1936
                if (j == 0x0e) {
1937
                        goto u3p_out;
1938
                }
1939
                continue;
1940
u3p_in:
1941
                tmport = wkport + 0x54;
1942
                outb(0x09, tmport);
1943
                tmport += 0x04;
1944
                outb(0x20, tmport);
1945
                tmport += 0x07;
1946
                k = 0;
1947
u3p_in1:
1948
                j = inb(tmport);
1949
                if ((j & 0x01) != 0) {
1950
                        tmport -= 0x06;
1951
                        mbuf[k++] = inb(tmport);
1952
                        tmport += 0x06;
1953
                        goto u3p_in1;
1954
                }
1955
                if ((j & 0x80) == 0x00) {
1956
                        goto u3p_in1;
1957
                }
1958
                tmport -= 0x08;
1959
                j = inb(tmport) & 0x0f;
1960
                if (j == 0x0f) {
1961
                        goto u3p_in;
1962
                }
1963
                if (j == 0x0a) {
1964
                        goto u3p_cmd;
1965
                }
1966
                if (j == 0x0e) {
1967
                        goto u3p_out;
1968
                }
1969
                continue;
1970
u3p_cmd:
1971
                tmport = wkport + 0x50;
1972
                outb(0x30, tmport);
1973
                tmport = wkport + 0x54;
1974
                outb(0x00, tmport);
1975
                tmport += 0x04;
1976
                outb(0x08, tmport);
1977
                tmport += 0x07;
1978
                while ((inb(tmport) & 0x80) == 0x00);
1979
                tmport -= 0x08;
1980
                j = inb(tmport);
1981
                if (j != 0x16) {
1982
                        if (j == 0x4e) {
1983
                                goto u3p_out;
1984
                        }
1985
                        continue;
1986
                }
1987
                if (mbuf[0] != 0x01) {
1988
                        goto chg_wide;
1989
                }
1990
                if (mbuf[1] != 0x06) {
1991
                        goto chg_wide;
1992
                }
1993
                if (mbuf[2] != 0x04) {
1994
                        goto chg_wide;
1995
                }
1996
                if (mbuf[3] == 0x09) {
1997
                   m = 1;
1998
                   m = m << i;
1999
                   dev->wide_idu |= m;
2000
                   dev->id[i].devspu = 0xce;
2001
                   continue;
2002
                }
2003
chg_wide:
2004
                tmport = wkport + 0x5b;
2005
                outb(0x01, tmport);
2006
                tmport = wkport + 0x43;
2007
                outb(satn[0], tmport++);
2008
                outb(satn[1], tmport++);
2009
                outb(satn[2], tmport++);
2010
                outb(satn[3], tmport++);
2011
                outb(satn[4], tmport++);
2012
                outb(satn[5], tmport++);
2013
                tmport += 0x06;
2014
                outb(0, tmport);
2015
                tmport += 0x02;
2016
                outb(dev->id[i].devspu, tmport++);
2017
                outb(0, tmport++);
2018
                outb(satn[6], tmport++);
2019
                outb(satn[7], tmport++);
2020
                tmport += 0x03;
2021
                outb(satn[8], tmport);
2022
                tmport += 0x07;
2023
 
2024
                while ((inb(tmport) & 0x80) == 0x00);
2025
                tmport -= 0x08;
2026
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2027
                        continue;
2028
                }
2029
                while (inb(tmport) != 0x8e);
2030
try_wide:
2031
                j = 0;
2032
                tmport = wkport + 0x54;
2033
                outb(0x05, tmport);
2034
                tmport += 0x04;
2035
                outb(0x20, tmport);
2036
                tmport += 0x07;
2037
 
2038
                while ((inb(tmport) & 0x80) == 0) {
2039
                        if ((inb(tmport) & 0x01) != 0) {
2040
                                tmport -= 0x06;
2041
                                outb(wide[j++], tmport);
2042
                                tmport += 0x06;
2043
                        }
2044
                }
2045
                tmport -= 0x08;
2046
                while ((inb(tmport) & 0x80) == 0x00);
2047
                j = inb(tmport) & 0x0f;
2048
                if (j == 0x0f) {
2049
                        goto widep_in;
2050
                }
2051
                if (j == 0x0a) {
2052
                        goto widep_cmd;
2053
                }
2054
                if (j == 0x0e) {
2055
                        goto try_wide;
2056
                }
2057
                continue;
2058
widep_out:
2059
                tmport = wkport + 0x58;
2060
                outb(0x20, tmport);
2061
                tmport += 0x07;
2062
                while ((inb(tmport) & 0x80) == 0) {
2063
                        if ((inb(tmport) & 0x01) != 0) {
2064
                                tmport -= 0x06;
2065
                                outb(0, tmport);
2066
                                tmport += 0x06;
2067
                        }
2068
                }
2069
                tmport -= 0x08;
2070
                j = inb(tmport) & 0x0f;
2071
                if (j == 0x0f) {
2072
                        goto widep_in;
2073
                }
2074
                if (j == 0x0a) {
2075
                        goto widep_cmd;
2076
                }
2077
                if (j == 0x0e) {
2078
                        goto widep_out;
2079
                }
2080
                continue;
2081
widep_in:
2082
                tmport = wkport + 0x54;
2083
                outb(0xff, tmport);
2084
                tmport += 0x04;
2085
                outb(0x20, tmport);
2086
                tmport += 0x07;
2087
                k = 0;
2088
widep_in1:
2089
                j = inb(tmport);
2090
                if ((j & 0x01) != 0) {
2091
                        tmport -= 0x06;
2092
                        mbuf[k++] = inb(tmport);
2093
                        tmport += 0x06;
2094
                        goto widep_in1;
2095
                }
2096
                if ((j & 0x80) == 0x00) {
2097
                        goto widep_in1;
2098
                }
2099
                tmport -= 0x08;
2100
                j = inb(tmport) & 0x0f;
2101
                if (j == 0x0f) {
2102
                        goto widep_in;
2103
                }
2104
                if (j == 0x0a) {
2105
                        goto widep_cmd;
2106
                }
2107
                if (j == 0x0e) {
2108
                        goto widep_out;
2109
                }
2110
                continue;
2111
widep_cmd:
2112
                tmport = wkport + 0x50;
2113
                outb(0x30, tmport);
2114
                tmport = wkport + 0x54;
2115
                outb(0x00, tmport);
2116
                tmport += 0x04;
2117
                outb(0x08, tmport);
2118
                tmport += 0x07;
2119
                while ((inb(tmport) & 0x80) == 0x00);
2120
                tmport -= 0x08;
2121
                j = inb(tmport);
2122
                if (j != 0x16) {
2123
                        if (j == 0x4e) {
2124
                                goto widep_out;
2125
                        }
2126
                        continue;
2127
                }
2128
                if (mbuf[0] != 0x01) {
2129
                        goto not_wide;
2130
                }
2131
                if (mbuf[1] != 0x02) {
2132
                        goto not_wide;
2133
                }
2134
                if (mbuf[2] != 0x03) {
2135
                        goto not_wide;
2136
                }
2137
                if (mbuf[3] != 0x01) {
2138
                        goto not_wide;
2139
                }
2140
                m = 1;
2141
                m = m << i;
2142
                dev->wide_idu |= m;
2143
not_wide:
2144
                if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
2145
                    ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
2146
                {
2147
                        m = 1;
2148
                        m = m << i;
2149
                        if ((dev->async & m) != 0)
2150
                        {
2151
                           goto set_sync;
2152
                        }
2153
                }
2154
                continue;
2155
set_sync:
2156
                if (dev->sp[i] == 0x02)
2157
                {
2158
                   synu[4]=0x0c;
2159
                   synuw[4]=0x0c;
2160
                }
2161
                else
2162
                {
2163
                   if (dev->sp[i] >= 0x03)
2164
                   {
2165
                      synu[4]=0x0a;
2166
                      synuw[4]=0x0a;
2167
                   }
2168
                }
2169
                tmport = wkport + 0x5b;
2170
                j = 0;
2171
                if ((m & dev->wide_idu) != 0) {
2172
                        j |= 0x01;
2173
                }
2174
                outb(j, tmport);
2175
                tmport = wkport + 0x43;
2176
                outb(satn[0], tmport++);
2177
                outb(satn[1], tmport++);
2178
                outb(satn[2], tmport++);
2179
                outb(satn[3], tmport++);
2180
                outb(satn[4], tmport++);
2181
                outb(satn[5], tmport++);
2182
                tmport += 0x06;
2183
                outb(0, tmport);
2184
                tmport += 0x02;
2185
                outb(dev->id[i].devspu, tmport++);
2186
                outb(0, tmport++);
2187
                outb(satn[6], tmport++);
2188
                outb(satn[7], tmport++);
2189
                tmport += 0x03;
2190
                outb(satn[8], tmport);
2191
                tmport += 0x07;
2192
 
2193
                while ((inb(tmport) & 0x80) == 0x00);
2194
                tmport -= 0x08;
2195
                if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2196
                        continue;
2197
                }
2198
                while (inb(tmport) != 0x8e);
2199
try_sync:
2200
                j = 0;
2201
                tmport = wkport + 0x54;
2202
                outb(0x06, tmport);
2203
                tmport += 0x04;
2204
                outb(0x20, tmport);
2205
                tmport += 0x07;
2206
 
2207
                while ((inb(tmport) & 0x80) == 0) {
2208
                        if ((inb(tmport) & 0x01) != 0) {
2209
                                tmport -= 0x06;
2210
                                if ((m & dev->wide_idu) != 0) {
2211
                                        if ((m & dev->ultra_map) != 0) {
2212
                                                outb(synuw[j++], tmport);
2213
                                        } else {
2214
                                                outb(synw[j++], tmport);
2215
                                        }
2216
                                } else {
2217
                                        if ((m & dev->ultra_map) != 0) {
2218
                                                outb(synu[j++], tmport);
2219
                                        } else {
2220
                                                outb(synn[j++], tmport);
2221
                                        }
2222
                                }
2223
                                tmport += 0x06;
2224
                        }
2225
                }
2226
                tmport -= 0x08;
2227
                while ((inb(tmport) & 0x80) == 0x00);
2228
                j = inb(tmport) & 0x0f;
2229
                if (j == 0x0f) {
2230
                        goto phase_ins;
2231
                }
2232
                if (j == 0x0a) {
2233
                        goto phase_cmds;
2234
                }
2235
                if (j == 0x0e) {
2236
                        goto try_sync;
2237
                }
2238
                continue;
2239
phase_outs:
2240
                tmport = wkport + 0x58;
2241
                outb(0x20, tmport);
2242
                tmport += 0x07;
2243
                while ((inb(tmport) & 0x80) == 0x00) {
2244
                        if ((inb(tmport) & 0x01) != 0x00) {
2245
                                tmport -= 0x06;
2246
                                outb(0x00, tmport);
2247
                                tmport += 0x06;
2248
                        }
2249
                }
2250
                tmport -= 0x08;
2251
                j = inb(tmport);
2252
                if (j == 0x85) {
2253
                        goto tar_dcons;
2254
                }
2255
                j &= 0x0f;
2256
                if (j == 0x0f) {
2257
                        goto phase_ins;
2258
                }
2259
                if (j == 0x0a) {
2260
                        goto phase_cmds;
2261
                }
2262
                if (j == 0x0e) {
2263
                        goto phase_outs;
2264
                }
2265
                continue;
2266
phase_ins:
2267
                tmport = wkport + 0x54;
2268
                outb(0x06, tmport);
2269
                tmport += 0x04;
2270
                outb(0x20, tmport);
2271
                tmport += 0x07;
2272
                k = 0;
2273
phase_ins1:
2274
                j = inb(tmport);
2275
                if ((j & 0x01) != 0x00) {
2276
                        tmport -= 0x06;
2277
                        mbuf[k++] = inb(tmport);
2278
                        tmport += 0x06;
2279
                        goto phase_ins1;
2280
                }
2281
                if ((j & 0x80) == 0x00) {
2282
                        goto phase_ins1;
2283
                }
2284
                tmport -= 0x08;
2285
                while ((inb(tmport) & 0x80) == 0x00);
2286
                j = inb(tmport);
2287
                if (j == 0x85) {
2288
                        goto tar_dcons;
2289
                }
2290
                j &= 0x0f;
2291
                if (j == 0x0f) {
2292
                        goto phase_ins;
2293
                }
2294
                if (j == 0x0a) {
2295
                        goto phase_cmds;
2296
                }
2297
                if (j == 0x0e) {
2298
                        goto phase_outs;
2299
                }
2300
                continue;
2301
phase_cmds:
2302
                tmport = wkport + 0x50;
2303
                outb(0x30, tmport);
2304
tar_dcons:
2305
                tmport = wkport + 0x54;
2306
                outb(0x00, tmport);
2307
                tmport += 0x04;
2308
                outb(0x08, tmport);
2309
                tmport += 0x07;
2310
                while ((inb(tmport) & 0x80) == 0x00);
2311
                tmport -= 0x08;
2312
                j = inb(tmport);
2313
                if (j != 0x16) {
2314
                        continue;
2315
                }
2316
                if (mbuf[0] != 0x01) {
2317
                        continue;
2318
                }
2319
                if (mbuf[1] != 0x03) {
2320
                        continue;
2321
                }
2322
                if (mbuf[4] == 0x00) {
2323
                        continue;
2324
                }
2325
                if (mbuf[3] > 0x64) {
2326
                        continue;
2327
                }
2328
                if (mbuf[4] > 0x0e) {
2329
                        mbuf[4] = 0x0e;
2330
                }
2331
                dev->id[i].devspu = mbuf[4];
2332
                if (mbuf[3] < 0x0c){
2333
                        j = 0xb0;
2334
                        goto set_syn_ok;
2335
                }
2336
                if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2337
                        j = 0xa0;
2338
                        goto set_syn_ok;
2339
                }
2340
                if (mbuf[3] < 0x1a) {
2341
                        j = 0x20;
2342
                        goto set_syn_ok;
2343
                }
2344
                if (mbuf[3] < 0x33) {
2345
                        j = 0x40;
2346
                        goto set_syn_ok;
2347
                }
2348
                if (mbuf[3] < 0x4c) {
2349
                        j = 0x50;
2350
                        goto set_syn_ok;
2351
                }
2352
                j = 0x60;
2353
              set_syn_ok:
2354
                dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
2355
        }
2356
}
2357
 
2358
/* return non-zero on detection */
2359
int atp870u_detect(Scsi_Host_Template * tpnt)
2360
{
2361
        unsigned char irq, h, k, m;
2362
        unsigned long flags;
2363
        unsigned int base_io, error, tmport;
2364
        unsigned short index = 0;
2365
        struct pci_dev *pdev[3];
2366
        unsigned char chip_ver[3], host_id;
2367
        unsigned short dev_id[3], n;
2368
        struct Scsi_Host *shpnt = NULL;
2369
        int tmpcnt = 0;
2370
        int count = 0;
2371
 
2372
        static unsigned short devid[9] = {
2373
          0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
2374
        };
2375
 
2376
        printk(KERN_INFO "aec671x_detect: \n");
2377
        if (!pci_present()) {
2378
                printk(KERN_INFO"   NO PCI SUPPORT.\n");
2379
                return count;
2380
        }
2381
        tpnt->proc_name = "atp870u";
2382
 
2383
        for (h = 0; h < 2; h++) {
2384
                struct atp_unit *dev = &atp_unit[h];
2385
                for(k=0;k<16;k++)
2386
                {
2387
                        dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
2388
                        dev->id[k].devspu=0x20;
2389
                        dev->id[k].devtypeu = 0;
2390
                        dev->id[k].curr_req = NULL;
2391
                }
2392
                dev->active_idu = 0;
2393
                dev->wide_idu = 0;
2394
                dev->host_idu = 0x07;
2395
                dev->quhdu = 0;
2396
                dev->quendu = 0;
2397
                pdev[h]=NULL;
2398
                pdev[2]=NULL;
2399
                dev->chip_veru = 0;
2400
                dev->last_cmd = 0xff;
2401
                dev->in_snd = 0;
2402
                dev->in_int = 0;
2403
                for (k = 0; k < qcnt; k++) {
2404
                        dev->querequ[k] = 0;
2405
                }
2406
                for (k = 0; k < 16; k++) {
2407
                        dev->id[k].curr_req = 0;
2408
                        dev->sp[k] = 0x04;
2409
                }
2410
        }
2411
        h = 0;
2412
        while (devid[h] != 0) {
2413
                pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
2414
                if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
2415
                        h++;
2416
                        index = 0;
2417
                        continue;
2418
                }
2419
                chip_ver[2] = 0;
2420
                dev_id[2] = devid[h];
2421
 
2422
                if (devid[h] == 0x8002) {
2423
                        error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
2424
                        if (chip_ver[2] < 2) {
2425
                                goto nxt_devfn;
2426
                        }
2427
                }
2428
                if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050)
2429
                {
2430
                        chip_ver[2] = 0x04;
2431
                }
2432
                pdev[tmpcnt] = pdev[2];
2433
                chip_ver[tmpcnt] = chip_ver[2];
2434
                dev_id[tmpcnt] = dev_id[2];
2435
                tmpcnt++;
2436
              nxt_devfn:
2437
                index++;
2438
                if (index > 3) {
2439
                        index = 0;
2440
                        h++;
2441
                }
2442
                if(tmpcnt>1)
2443
                        break;
2444
        }
2445
        for (h = 0; h < 2; h++) {
2446
                struct atp_unit *dev=&atp_unit[h];
2447
                if (pdev[h]==NULL) {
2448
                        return count;
2449
                }
2450
 
2451
                /* Found an atp870u/w. */
2452
                base_io = pci_resource_start(pdev[h], 0);
2453
                irq = pdev[h]->irq;
2454
 
2455
                if (dev_id[h] != 0x8081)
2456
                {
2457
                   error = pci_read_config_byte(pdev[h],0x49,&host_id);
2458
 
2459
                   base_io &= 0xfffffff8;
2460
 
2461
                   if (check_region(base_io,0x40) != 0)
2462
                   {
2463
                           return 0;
2464
                   }
2465
                   printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.\n"
2466
                          ,h, base_io, irq);
2467
                   dev->ioport = base_io;
2468
                   dev->pciport = base_io + 0x20;
2469
                   dev->deviceid = dev_id[h];
2470
                   irqnumu[h] = irq;
2471
                   host_id &= 0x07;
2472
                   dev->host_idu = host_id;
2473
                   dev->chip_veru = chip_ver[h];
2474
 
2475
                   tmport = base_io + 0x22;
2476
                   dev->scam_on = inb(tmport);
2477
                   tmport += 0x0b;
2478
                   dev->global_map = inb(tmport++);
2479
                   dev->ultra_map = inw(tmport);
2480
                   if (dev->ultra_map == 0) {
2481
                           dev->scam_on = 0x00;
2482
                           dev->global_map = 0x20;
2483
                           dev->ultra_map = 0xffff;
2484
                   }
2485
                   shpnt = scsi_register(tpnt, 4);
2486
                   if(shpnt==NULL)
2487
                           return count;
2488
 
2489
                   save_flags(flags);
2490
                   cli();
2491
                   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2492
                           printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2493
                           goto unregister;
2494
                   }
2495
 
2496
                   if (chip_ver[h] > 0x07)           /* check if atp876 chip   */
2497
                   {                                 /* then enable terminator */
2498
                      tmport = base_io + 0x3e;
2499
                      outb(0x00, tmport);
2500
                   }
2501
 
2502
                   tmport = base_io + 0x3a;
2503
                   k = (inb(tmport) & 0xf3) | 0x10;
2504
                   outb(k, tmport);
2505
                   outb((k & 0xdf), tmport);
2506
                   mydlyu(0x8000);
2507
                   outb(k, tmport);
2508
                   mydlyu(0x8000);
2509
                   tmport = base_io;
2510
                   outb((host_id | 0x08), tmport);
2511
                   tmport += 0x18;
2512
                   outb(0, tmport);
2513
                   tmport += 0x07;
2514
                   while ((inb(tmport) & 0x80) == 0);
2515
                   tmport -= 0x08;
2516
                   inb(tmport);
2517
                   tmport = base_io + 1;
2518
                   outb(8, tmport++);
2519
                   outb(0x7f, tmport);
2520
                   tmport = base_io + 0x11;
2521
                   outb(0x20, tmport);
2522
 
2523
                   tscam(h);
2524
                   is870(h, base_io);
2525
                   tmport = base_io + 0x3a;
2526
                   outb((inb(tmport) & 0xef), tmport);
2527
                   tmport++;
2528
                   outb((inb(tmport) | 0x20),tmport);
2529
                }
2530
                else
2531
                {
2532
                   base_io &= 0xfffffff8;
2533
 
2534
                   if (check_region(base_io,0x60) != 0)
2535
                   {
2536
                           return 0;
2537
                   }
2538
                   host_id = inb(base_io + 0x39);
2539
                   host_id >>= 0x04;
2540
 
2541
                   printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d    IO:%x, IRQ:%d.\n"
2542
                          ,h, base_io, irq);
2543
                   dev->ioport = base_io + 0x40;
2544
                   dev->pciport = base_io + 0x28;
2545
                   dev->deviceid = dev_id[h];
2546
                   irqnumu[h] = irq;
2547
                   dev->host_idu = host_id;
2548
                   dev->chip_veru = chip_ver[h];
2549
 
2550
                   tmport = base_io + 0x22;
2551
                   dev->scam_on = inb(tmport);
2552
                   tmport += 0x13;
2553
                   dev->global_map = inb(tmport);
2554
                   tmport += 0x07;
2555
                   dev->ultra_map = inw(tmport);
2556
 
2557
                   n=0x3f09;
2558
next_fblk:
2559
                   if (n >= 0x4000)
2560
                   {
2561
                      goto flash_ok;
2562
                   }
2563
                   m=0;
2564
                   outw(n,base_io + 0x34);
2565
                   n += 0x0002;
2566
                   if (inb(base_io + 0x30) == 0xff)
2567
                   {
2568
                      goto flash_ok;
2569
                   }
2570
                   dev->sp[m++]=inb(base_io + 0x30);
2571
                   dev->sp[m++]=inb(base_io + 0x31);
2572
                   dev->sp[m++]=inb(base_io + 0x32);
2573
                   dev->sp[m++]=inb(base_io + 0x33);
2574
                   outw(n,base_io + 0x34);
2575
                   n += 0x0002;
2576
                   dev->sp[m++]=inb(base_io + 0x30);
2577
                   dev->sp[m++]=inb(base_io + 0x31);
2578
                   dev->sp[m++]=inb(base_io + 0x32);
2579
                   dev->sp[m++]=inb(base_io + 0x33);
2580
                   outw(n,base_io + 0x34);
2581
                   n += 0x0002;
2582
                   dev->sp[m++]=inb(base_io + 0x30);
2583
                   dev->sp[m++]=inb(base_io + 0x31);
2584
                   dev->sp[m++]=inb(base_io + 0x32);
2585
                   dev->sp[m++]=inb(base_io + 0x33);
2586
                   outw(n,base_io + 0x34);
2587
                   n += 0x0002;
2588
                   dev->sp[m++]=inb(base_io + 0x30);
2589
                   dev->sp[m++]=inb(base_io + 0x31);
2590
                   dev->sp[m++]=inb(base_io + 0x32);
2591
                   dev->sp[m++]=inb(base_io + 0x33);
2592
                   n += 0x0018;
2593
                   goto next_fblk;
2594
flash_ok:
2595
                   outw(0,base_io + 0x34);
2596
                   dev->ultra_map=0;
2597
                   dev->async = 0;
2598
                   for (k=0; k < 16; k++)
2599
                   {
2600
                       n=1;
2601
                       n = n << k;
2602
                       if (dev->sp[k] > 1)
2603
                       {
2604
                          dev->ultra_map |= n;
2605
                       }
2606
                       else
2607
                       {
2608
                          if (dev->sp[k] == 0)
2609
                          {
2610
                             dev->async |= n;
2611
                          }
2612
                       }
2613
                   }
2614
                   dev->async = ~(dev->async);
2615
                   outb(dev->global_map,base_io + 0x35);
2616
 
2617
                   shpnt = scsi_register(tpnt, 4);
2618
                   if(shpnt==NULL)
2619
                           return count;
2620
 
2621
                   save_flags(flags);
2622
                   cli();
2623
                   if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
2624
                           printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2625
                           goto unregister;
2626
                   }
2627
 
2628
                   tmport = base_io + 0x38;
2629
                   k = inb(tmport) & 0x80;
2630
                   outb(k, tmport);
2631
                   tmport += 0x03;
2632
                   outb(0x20, tmport);
2633
                   mydlyu(0x8000);
2634
                   outb(0, tmport);
2635
                   mydlyu(0x8000);
2636
                   tmport = base_io + 0x5b;
2637
                   inb(tmport);
2638
                   tmport -= 0x04;
2639
                   inb(tmport);
2640
                   tmport = base_io + 0x40;
2641
                   outb((host_id | 0x08), tmport);
2642
                   tmport += 0x18;
2643
                   outb(0, tmport);
2644
                   tmport += 0x07;
2645
                   while ((inb(tmport) & 0x80) == 0);
2646
                   tmport -= 0x08;
2647
                   inb(tmport);
2648
                   tmport = base_io + 0x41;
2649
                   outb(8, tmport++);
2650
                   outb(0x7f, tmport);
2651
                   tmport = base_io + 0x51;
2652
                   outb(0x20, tmport);
2653
 
2654
                   tscam(h);
2655
                   is880(h, base_io);
2656
                   tmport = base_io + 0x38;
2657
                   outb(0xb0, tmport);
2658
                }
2659
 
2660
                atp_host[h] = shpnt;
2661
                if (dev->chip_veru == 4) {
2662
                        shpnt->max_id = 16;
2663
                }
2664
                shpnt->this_id = host_id;
2665
                shpnt->unique_id = base_io;
2666
                shpnt->io_port = base_io;
2667
                if (dev_id[h] == 0x8081)
2668
                {
2669
                   shpnt->n_io_port = 0x60;        /* Number of bytes of I/O space used */
2670
                }
2671
                else
2672
                {
2673
                   shpnt->n_io_port = 0x40;        /* Number of bytes of I/O space used */
2674
                }
2675
                shpnt->irq = irq;
2676
                restore_flags(flags);
2677
                if (dev_id[h] == 0x8081)
2678
                {
2679
                   request_region(base_io, 0x60, "atp870u");       /* Register the IO ports that we use */
2680
                }
2681
                else
2682
                {
2683
                   request_region(base_io, 0x40, "atp870u");       /* Register the IO ports that we use */
2684
                }
2685
                count++;
2686
                index++;
2687
                continue;
2688
unregister:
2689
                scsi_unregister(shpnt);
2690
                restore_flags(flags);
2691
                index++;
2692
                continue;
2693
        }
2694
 
2695
        return count;
2696
}
2697
 
2698
/* The abort command does not leave the device in a clean state where
2699
   it is available to be used again.  Until this gets worked out, we will
2700
   leave it commented out.  */
2701
 
2702
int atp870u_abort(Scsi_Cmnd * SCpnt)
2703
{
2704
        unsigned char h, j, k;
2705
        Scsi_Cmnd *workrequ;
2706
        unsigned int tmport;
2707
        struct atp_unit *dev;
2708
        for (h = 0; h <= admaxu; h++) {
2709
                if (SCpnt->host == atp_host[h]) {
2710
                        goto find_adp;
2711
                }
2712
        }
2713
        panic("Abort host not found !");
2714
find_adp:
2715
        dev=&atp_unit[h];
2716
        printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
2717
        printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
2718
        tmport = dev->ioport;
2719
        for (j = 0; j < 0x17; j++) {
2720
                printk(" r%2x=%2x", j, inb(tmport++));
2721
        }
2722
        tmport += 0x05;
2723
        printk(" r1c=%2x", inb(tmport));
2724
        tmport += 0x03;
2725
        printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
2726
        tmport= dev->pciport;
2727
        printk(" r20=%2x", inb(tmport));
2728
        tmport += 0x02;
2729
        printk(" r22=%2x", inb(tmport));
2730
        tmport = dev->ioport + 0x3a;
2731
        printk(" r3a=%2x \n",inb(tmport));
2732
        tmport = dev->ioport + 0x3b;
2733
        printk(" r3b=%2x \n",inb(tmport));
2734
        for(j=0;j<16;j++)
2735
        {
2736
           if (dev->id[j].curr_req != NULL)
2737
           {
2738
                workrequ = dev->id[j].curr_req;
2739
                printk("\n que cdb= ");
2740
                for (k=0; k < workrequ->cmd_len; k++)
2741
                {
2742
                    printk(" %2x ",workrequ->cmnd[k]);
2743
                }
2744
                printk(" last_lenu= %lx ",dev->id[j].last_lenu);
2745
           }
2746
        }
2747
        return (SCSI_ABORT_SNOOZE);
2748
}
2749
 
2750
int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
2751
{
2752
        unsigned char h;
2753
        struct atp_unit *dev;
2754
        /*
2755
         * See if a bus reset was suggested.
2756
         */
2757
        for (h = 0; h <= admaxu; h++) {
2758
                if (SCpnt->host == atp_host[h]) {
2759
                        goto find_host;
2760
                }
2761
        }
2762
        panic("Reset bus host not found !");
2763
find_host:
2764
        dev=&atp_unit[h];
2765
/*      SCpnt->result = 0x00080000;
2766
        SCpnt->scsi_done(SCpnt);
2767
        dev->working=0;
2768
        dev->quhdu=0;
2769
        dev->quendu=0;
2770
        return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);  */
2771
        return (SCSI_RESET_SNOOZE);
2772
}
2773
 
2774
const char *atp870u_info(struct Scsi_Host *notused)
2775
{
2776
        static char buffer[128];
2777
 
2778
        strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
2779
 
2780
        return buffer;
2781
}
2782
 
2783
int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
2784
{
2785
        return -ENOSYS;         /* Currently this is a no-op */
2786
}
2787
 
2788
#define BLS buffer + len + size
2789
int atp870u_proc_info(char *buffer, char **start, off_t offset, int length,
2790
                      int hostno, int inout)
2791
{
2792
        struct Scsi_Host *HBAptr;
2793
        static u8 buff[512];
2794
        int i;
2795
        int size = 0;
2796
        int len = 0;
2797
        off_t begin = 0;
2798
        off_t pos = 0;
2799
 
2800
        HBAptr = NULL;
2801
        for (i = 0; i < 2; i++) {
2802
                if ((HBAptr = atp_host[i]) != NULL) {
2803
                        if (HBAptr->host_no == hostno) {
2804
                                break;
2805
                        }
2806
                        HBAptr = NULL;
2807
                }
2808
        }
2809
 
2810
        if (HBAptr == NULL) {
2811
                size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
2812
                len += size;
2813
                pos = begin + len;
2814
                size = 0;
2815
                goto stop_output;
2816
        }
2817
        if (inout == TRUE) {    /* Has data been written to the file? */
2818
                return (atp870u_set_info(buffer, length, HBAptr));
2819
        }
2820
        if (offset == 0) {
2821
                memset(buff, 0, sizeof(buff));
2822
        }
2823
        size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
2824
        len += size;
2825
        pos = begin + len;
2826
        size = 0;
2827
 
2828
        size += sprintf(BLS, "\n");
2829
        size += sprintf(BLS, "Adapter Configuration:\n");
2830
        size += sprintf(BLS, "               Base IO: %#.4lx\n", HBAptr->io_port);
2831
        size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
2832
        len += size;
2833
        pos = begin + len;
2834
        size = 0;
2835
 
2836
stop_output:
2837
        *start = buffer + (offset - begin);     /* Start of wanted data */
2838
        len -= (offset - begin);        /* Start slop */
2839
        if (len > length) {
2840
                len = length;   /* Ending slop */
2841
        }
2842
        return (len);
2843
}
2844
 
2845
#include "sd.h"
2846
 
2847
int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
2848
{
2849
        int heads, sectors, cylinders;
2850
 
2851
        heads = 64;
2852
        sectors = 32;
2853
        cylinders = disk->capacity / (heads * sectors);
2854
 
2855
        if (cylinders > 1024) {
2856
                heads = 255;
2857
                sectors = 63;
2858
                cylinders = disk->capacity / (heads * sectors);
2859
        }
2860
        ip[0] = heads;
2861
        ip[1] = sectors;
2862
        ip[2] = cylinders;
2863
 
2864
        return 0;
2865
}
2866
 
2867
 
2868
int atp870u_release (struct Scsi_Host *pshost)
2869
{
2870
        int h;
2871
        for (h = 0; h <= admaxu; h++)
2872
        {
2873
                if (pshost == atp_host[h]) {
2874
                        int k;
2875
                        free_irq (pshost->irq, &atp_unit[h]);
2876
                        release_region (pshost->io_port, pshost->n_io_port);
2877
                        scsi_unregister(pshost);
2878
                        for(k=0;k<16;k++)
2879
                                kfree(atp_unit[h].id[k].prd_tableu);
2880
                        return 0;
2881
                }
2882
        }
2883
        panic("atp870u: bad scsi host passed.\n");
2884
 
2885
}
2886
MODULE_LICENSE("GPL");
2887
 
2888
static Scsi_Host_Template driver_template = ATP870U;
2889
#include "scsi_module.c"

powered by: WebSVN 2.1.0

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