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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [atp870u.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: atp870u.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
2
 *  linux/kernel/atp870u.c
3
 *
4
 *  Copyright (C) 1997  Wu Ching Chen
5
 *
6
 */
7
 
8
#include <linux/module.h>
9
 
10
#include <linux/kernel.h>
11
#include <linux/head.h>
12
#include <linux/types.h>
13
#include <linux/string.h>
14
#include <linux/ioport.h>
15
#include <linux/delay.h>
16
#include <linux/sched.h>
17
#include <linux/proc_fs.h>
18
#include <asm/system.h>
19
#include <asm/io.h>
20
#include <linux/bios32.h>
21
#include <linux/pci.h>
22
#include <linux/blk.h>
23
#include "scsi.h"
24
#include "hosts.h"
25
 
26
 
27
#include "atp870u.h"
28
#include <linux/config.h>       /* for CONFIG_PCI */
29
 
30
#include<linux/stat.h>
31
 
32
struct proc_dir_entry proc_scsi_atp870u = {
33
    PROC_SCSI_ATP870U, 7, "atp870u",
34
    S_IFDIR | S_IRUGO | S_IXUGO, 2
35
};
36
 
37
void mydlyu(unsigned int);
38
/*
39
static const char RCSid[] = "$Header: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/rc203soc/sw/uClinux/drivers/scsi/atp870u.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $";
40
*/
41
 
42
static unsigned char admaxu=1,host_idu[2],chip_veru[2],scam_on[2],global_map[2];
43
static unsigned short int active_idu[2],wide_idu[2],sync_idu,ultra_map[2];
44
static int  workingu[2]={0,0};
45
static Scsi_Cmnd *querequ[2][qcnt],*curr_req[2][16];
46
static unsigned char devspu[2][16] = {{0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
47
                                0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
48
                               {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
49
                                0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20}};
50
static unsigned char dirctu[2][16],last_cmd[2],in_snd[2],in_int[2];
51
static unsigned char ata_cdbu[2][16];
52
static unsigned int ioportu[2]={0,0};
53
static unsigned int irqnumu[2]={0,0};
54
static unsigned short int pciportu[2];
55
static unsigned long prdaddru[2][16],tran_lenu[2][16],last_lenu[2][16];
56
static unsigned char prd_tableu[2][16][1024];
57
static unsigned char *prd_posu[2][16];
58
static unsigned char quhdu[2],quendu[2];
59
static unsigned char devtypeu[2][16] = {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
60
                                 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
61
static struct Scsi_Host * atp_host[2]={NULL,NULL};
62
 
63
static void atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
64
{
65
    unsigned short int  tmpcip,id;
66
    unsigned char       i,j,h,tarid,lun;
67
    unsigned char  *prd;
68
    Scsi_Cmnd *workrequ;
69
    unsigned int workportu,tmport;
70
    unsigned long adrcntu,k;
71
    int      errstus;
72
 
73
    for ( h=0; h < 2; h++ )
74
    {
75
        if ( ( irq & 0x0f ) == irqnumu[h] )
76
        {
77
           goto irq_numok;
78
        }
79
    }
80
    return;
81
irq_numok:
82
    in_int[h]=1;
83
    workportu=ioportu[h];
84
    tmport=workportu;
85
 
86
    if ( workingu[h] != 0 )
87
    {
88
       tmport += 0x1f;
89
       j=inb(tmport);
90
       tmpcip=pciportu[h];
91
       if ((inb(tmpcip) & 0x08) != 0)
92
       {
93
          tmpcip += 0x2;
94
          while((inb(tmpcip) & 0x08) != 0);
95
       }
96
       tmpcip=pciportu[h];
97
       outb(0x00,tmpcip);
98
       tmport -=0x08;
99
       i=inb(tmport);
100
       if ((j & 0x40) == 0)
101
       {
102
          if ((last_cmd[h] & 0x40) == 0)
103
          {
104
             last_cmd[h]=0xff;
105
          }
106
       }
107
       else
108
       {
109
          last_cmd[h] |= 0x40;
110
       }
111
       tmport -= 0x02;
112
       tarid=inb(tmport);
113
       tmport += 0x02;
114
       if ((tarid & 0x40) != 0)
115
       {
116
          tarid=(tarid & 0x07) | 0x08;
117
       }
118
       else
119
       {
120
          tarid &= 0x07;
121
       }
122
       if ( i == 0x85 )
123
       {
124
          if (wide_idu[h] != 0)
125
          {
126
             tmport=workportu+0x1b;
127
             j=inb(tmport) & 0x0e;
128
             j |= 0x01;
129
             outb(j,tmport);
130
          }
131
          if (((quhdu[h] != quendu[h]) || (last_cmd[h] != 0xff)) &&
132
              (in_snd[h] == 0))
133
          {
134
             send_s870(h);
135
          }
136
          in_int[h]=0;
137
          return;
138
       }
139
       if ( i == 0x21 )
140
       {
141
          tmport -= 0x05;
142
          adrcntu=0;
143
          ((unsigned char *)&adrcntu)[2]=inb(tmport++);
144
          ((unsigned char *)&adrcntu)[1]=inb(tmport++);
145
          ((unsigned char *)&adrcntu)[0]=inb(tmport);
146
          k=last_lenu[h][tarid];
147
          k -= adrcntu;
148
          tran_lenu[h][tarid]= k;
149
          last_lenu[h][tarid]=adrcntu;
150
          tmport -= 0x04;
151
          outb(0x41,tmport);
152
          tmport += 0x08;
153
          outb(0x08,tmport);
154
          in_int[h]=0;
155
          return ;
156
       }
157
 
158
       if ((i == 0x80) || (i == 0x8f))
159
       {
160
          lun=0;
161
          tmport -= 0x07;
162
          j=inb(tmport);
163
          if ( j == 0x44 )
164
          {
165
             tmport += 0x0d;
166
             lun=inb(tmport) & 0x07;
167
          }
168
          else
169
          {
170
             if ( j == 0x41 )
171
             {
172
                tmport += 0x02;
173
                adrcntu=0;
174
                ((unsigned char *)&adrcntu)[2]=inb(tmport++);
175
                ((unsigned char *)&adrcntu)[1]=inb(tmport++);
176
                ((unsigned char *)&adrcntu)[0]=inb(tmport);
177
                k=last_lenu[h][tarid];
178
                k -= adrcntu;
179
                tran_lenu[h][tarid]= k;
180
                last_lenu[h][tarid]=adrcntu;
181
                tmport += 0x04;
182
                outb(0x08,tmport);
183
                in_int[h]=0;
184
                return ;
185
             }
186
             else
187
             {
188
                outb(0x46,tmport);
189
                dirctu[h][tarid]=0x00;
190
                tmport += 0x02;
191
                outb(0x00,tmport++);
192
                outb(0x00,tmport++);
193
                outb(0x00,tmport++);
194
                tmport+=0x03;
195
                outb(0x08,tmport);
196
                in_int[h]=0;
197
                return;
198
             }
199
          }
200
          tmport=workportu + 0x10;
201
          outb(0x45,tmport);
202
          tmport += 0x06;
203
          tarid=inb(tmport);
204
          if ((tarid & 0x10) != 0)
205
          {
206
             tarid=(tarid & 0x07) | 0x08;
207
          }
208
          else
209
          {
210
             tarid &= 0x07;
211
          }
212
          workrequ=curr_req[h][tarid];
213
          tmport=workportu + 0x0f;
214
          outb(lun,tmport);
215
          tmport += 0x02;
216
          outb(devspu[h][tarid],tmport++);
217
          adrcntu=tran_lenu[h][tarid];
218
          k=last_lenu[h][tarid];
219
          outb(((unsigned char *)&k)[2],tmport++);
220
          outb(((unsigned char *)&k)[1],tmport++);
221
          outb(((unsigned char *)&k)[0],tmport++);
222
          j=tarid;
223
          if ( tarid > 7 )
224
          {
225
             j = (j & 0x07) | 0x40;
226
          }
227
          j |= dirctu[h][tarid];
228
          outb(j,tmport++);
229
          outb(0x80,tmport);
230
          tmport=workportu + 0x1b;
231
          j=inb(tmport) & 0x0e;
232
          id=1;
233
          id=id << tarid;
234
          if ((id & wide_idu[h]) != 0)
235
          {
236
             j |= 0x01;
237
          }
238
          outb(j,tmport);
239
          if ( last_lenu[h][tarid] == 0 )
240
          {
241
             tmport=workportu + 0x18;
242
             outb(0x08,tmport);
243
             in_int[h]=0;
244
             return ;
245
          }
246
          prd=prd_posu[h][tarid];
247
          while ( adrcntu != 0 )
248
          {
249
               id=((unsigned short int *)(prd))[2];
250
               if ( id == 0 )
251
               {
252
                  k=0x10000;
253
               }
254
               else
255
               {
256
                  k=id;
257
               }
258
               if ( k > adrcntu )
259
               {
260
                  ((unsigned short int *)(prd))[2] =(unsigned short int)
261
                                                     (k - adrcntu);
262
                  ((unsigned long *)(prd))[0] += adrcntu;
263
                  adrcntu=0;
264
                  prd_posu[h][tarid]=prd;
265
               }
266
               else
267
               {
268
                  adrcntu -= k;
269
                  prdaddru[h][tarid] += 0x08;
270
                  prd += 0x08;
271
                  if ( adrcntu == 0 )
272
                  {
273
                     prd_posu[h][tarid]=prd;
274
                  }
275
               }
276
          }
277
          tmpcip=pciportu[h] + 0x04;
278
          outl(prdaddru[h][tarid],tmpcip);
279
          tmpcip -= 0x02;
280
          outb(0x06,tmpcip);
281
          outb(0x00,tmpcip);
282
          tmpcip -= 0x02;
283
          tmport=workportu + 0x18;
284
          if ( dirctu[h][tarid] != 0 )
285
          {
286
             outb(0x08,tmport);
287
             outb(0x01,tmpcip);
288
             in_int[h]=0;
289
             return;
290
          }
291
          outb(0x08,tmport);
292
          outb(0x09,tmpcip);
293
          in_int[h]=0;
294
          return;
295
       }
296
 
297
       workrequ=curr_req[h][tarid];
298
       if ( i == 0x42 )
299
       {
300
          errstus=0x02;
301
          workrequ->result=errstus;
302
          goto go_42;
303
       }
304
       if ( i == 0x16 )
305
       {
306
          errstus=0;
307
          tmport -= 0x08;
308
          errstus=inb(tmport);
309
          workrequ->result=errstus;
310
/*        if ( errstus == 0x02 )
311
          {
312
             tmport +=0x10;
313
             if ((inb(tmport) & 0x80) != 0)
314
             {
315
                printk(" autosense ");
316
             }
317
             tmport -=0x09;
318
             outb(0,tmport);
319
             tmport=workportu+0x3a;
320
             outb((unsigned char)(inb(tmport) | 0x10),tmport);
321
             tmport -= 0x39;
322
 
323
             outb(0x08,tmport++);
324
             outb(0x7f,tmport++);
325
             outb(0x03,tmport++);
326
             outb(0x00,tmport++);
327
             outb(0x00,tmport++);
328
             outb(0x00,tmport++);
329
             outb(0x0e,tmport++);
330
             outb(0x00,tmport);
331
             tmport+=0x07;
332
             outb(0x00,tmport++);
333
             tmport++;
334
             outb(devspu[h][workrequ->target],tmport++);
335
             outb(0x00,tmport++);
336
             outb(0x00,tmport++);
337
             outb(0x0e,tmport++);
338
             tmport+=0x03;
339
             outb(0x09,tmport);
340
             tmport+=0x07;
341
             i=0;
342
             adrcntu=(unsigned long)(&workrequ->sense_buffer[0]);
343
get_sens:
344
             j=inb(tmport);
345
             if ((j & 0x01) != 0)
346
             {
347
                tmport-=0x06;
348
                (unsigned char)(((caddr_t) adrcntu)[i++])=inb(tmport);
349
                tmport+=0x06;
350
                goto get_sens;
351
             }
352
             if ((j & 0x80) == 0)
353
             {
354
                goto get_sens;
355
             }
356
             if ((j & 0x40) == 0)
357
             {
358
                tmport-=0x08;
359
                i=inb(tmport);
360
             }
361
             tmport=workportu+0x3a;
362
             outb((unsigned char)(inb(tmport) & 0xef),tmport);
363
             tmport=workportu+0x01;
364
             outb(0x2c,tmport);
365
             tmport += 0x15;
366
             outb(0x80,tmport);
367
          }   */
368
go_42:
369
          (*workrequ->scsi_done)(workrequ);
370
          curr_req[h][tarid]=0;
371
          workingu[h]--;
372
          if (wide_idu[h] != 0)
373
          {
374
             tmport=workportu+0x1b;
375
             j=inb(tmport) & 0x0e;
376
             j |= 0x01;
377
             outb(j,tmport);
378
          }
379
          if (((last_cmd[h] != 0xff) || (quhdu[h] != quendu[h])) &&
380
              (in_snd[h] == 0))
381
          {
382
             send_s870(h);
383
          }
384
          in_int[h]=0;
385
          return;
386
       }
387
   if ( i == 0x4f )
388
   {
389
      i=0x89;
390
   }
391
   i &= 0x0f;
392
   if ( i == 0x09 )
393
   {
394
      tmpcip=tmpcip+4;
395
      outl(prdaddru[h][tarid],tmpcip);
396
      tmpcip=tmpcip-2;
397
      outb(0x06,tmpcip);
398
      outb(0x00,tmpcip);
399
      tmpcip=tmpcip-2;
400
      tmport=workportu+0x10;
401
      outb(0x41,tmport);
402
      dirctu[h][tarid]=0x00;
403
      tmport += 0x08;
404
      outb(0x08,tmport);
405
      outb(0x09,tmpcip);
406
      in_int[h]=0;
407
      return;
408
   }
409
   if ( i == 0x08 )
410
   {
411
      tmpcip=tmpcip+4;
412
      outl(prdaddru[h][tarid],tmpcip);
413
      tmpcip=tmpcip-2;
414
      outb(0x06,tmpcip);
415
      outb(0x00,tmpcip);
416
      tmpcip=tmpcip-2;
417
      tmport=workportu+0x10;
418
      outb(0x41,tmport);
419
      tmport += 0x05;
420
      outb((unsigned char)(inb(tmport) | 0x20),tmport);
421
      dirctu[h][tarid]=0x20;
422
      tmport += 0x03;
423
      outb(0x08,tmport);
424
      outb(0x01,tmpcip);
425
      in_int[h]=0;
426
      return;
427
   }
428
   tmport -= 0x07;
429
   if ( i == 0x0a )
430
   {
431
      outb(0x30,tmport);
432
   }
433
   else
434
   {
435
      outb(0x46,tmport);
436
   }
437
   dirctu[h][tarid]=0x00;
438
   tmport += 0x02;
439
   outb(0x00,tmport++);
440
   outb(0x00,tmport++);
441
   outb(0x00,tmport++);
442
   tmport+=0x03;
443
   outb(0x08,tmport);
444
   in_int[h]=0;
445
   return;
446
  }
447
  else
448
  {
449
     tmport=workportu+0x17;
450
     inb(tmport);
451
     workingu[h]=0;
452
     in_int[h]=0;
453
     return;
454
  }
455
}
456
 
457
int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done)(Scsi_Cmnd *))
458
{
459
    unsigned char i,h;
460
    unsigned long flags;
461
    unsigned short int m;
462
    unsigned int tmport;
463
 
464
    for( h=0; h <= admaxu; h++ )
465
    {
466
       if ( req_p->host == atp_host[h] )
467
       {
468
          goto host_ok;
469
       }
470
    }
471
    return 0;
472
host_ok:
473
   if ( req_p->channel != 0 )
474
   {
475
      req_p->result = 0x00040000;
476
      done(req_p);
477
      return 0;
478
   }
479
   m=1;
480
   m=  m << req_p->target;
481
   if ( ( m & active_idu[h] ) == 0 )
482
   {
483
      req_p->result = 0x00040000;
484
      done(req_p);
485
      return 0;
486
   }
487
   if (done)
488
   {
489
      req_p->scsi_done = done;
490
   }
491
   else
492
   {
493
      printk("atp870u_queuecommand: done can't be NULL\n");
494
      req_p->result = 0;
495
      done(req_p);
496
      return 0;
497
   }
498
   quendu[h]++;
499
   if ( quendu[h] >= qcnt )
500
   {
501
      quendu[h]=0;
502
   }
503
   wait_que_empty:
504
     if ( quhdu[h] == quendu[h] )
505
     {
506
        goto wait_que_empty;
507
     }
508
     save_flags(flags);
509
     cli();
510
     querequ[h][quendu[h]]=req_p;
511
     if ( quendu[h] == 0 )
512
     {
513
        i=qcnt-1;
514
     }
515
     else
516
     {
517
        i=quendu[h]-1;
518
     }
519
     tmport = ioportu[h]+0x1c;
520
     restore_flags(flags);
521
     if ((inb(tmport) == 0) && (in_int[h] == 0) && (in_snd[h] == 0))
522
     {
523
         send_s870(h);
524
     }
525
     return 0;
526
}
527
 
528
void mydlyu(unsigned int dlycnt )
529
{
530
    unsigned int i ;
531
    for ( i = 0 ; i < dlycnt ; i++ )
532
    {
533
       inb(0x80);
534
    }
535
}
536
 
537
void send_s870(unsigned char h)
538
{
539
     unsigned int  tmport;
540
     Scsi_Cmnd *workrequ;
541
     unsigned long flags;
542
     unsigned int   i;
543
     unsigned char  j,tarid;
544
     unsigned char  *prd;
545
     unsigned short int   tmpcip,w;
546
     unsigned long  l,bttl;
547
     unsigned int workportu;
548
     struct scatterlist * sgpnt;
549
 
550
        save_flags(flags);
551
        cli();
552
        if ( in_snd[h] != 0 )
553
        {
554
           restore_flags(flags);
555
           return;
556
        }
557
        in_snd[h]=1;
558
        if ((last_cmd[h] != 0xff) && ((last_cmd[h] & 0x40) != 0))
559
        {
560
           last_cmd[h] &= 0x0f;
561
           workrequ=curr_req[h][last_cmd[h]];
562
           goto cmd_subp;
563
        }
564
        workingu[h]++;
565
        j=quhdu[h];
566
        quhdu[h]++;
567
        if ( quhdu[h] >= qcnt )
568
        {
569
           quhdu[h]=0;
570
        }
571
        workrequ=querequ[h][quhdu[h]];
572
        if ( curr_req[h][workrequ->target] == 0 )
573
        {
574
           curr_req[h][workrequ->target]=workrequ;
575
           last_cmd[h]=workrequ->target;
576
           goto cmd_subp;
577
        }
578
        quhdu[h]=j;
579
        workingu[h]--;
580
        in_snd[h]=0;
581
        restore_flags(flags);
582
        return ;
583
cmd_subp:
584
   workportu=ioportu[h];
585
   tmport=workportu+0x1f;
586
   if ((inb(tmport) & 0xb0) != 0)
587
   {
588
      goto abortsnd;
589
   }
590
   tmport=workportu+0x1c;
591
   if ( inb(tmport) == 0 )
592
   {
593
      goto oktosend;
594
   }
595
abortsnd:
596
   last_cmd[h] |= 0x40;
597
   in_snd[h]=0;
598
   restore_flags(flags);
599
   return;
600
oktosend:
601
   memcpy(&ata_cdbu[h][0], &workrequ->cmnd[0], workrequ->cmd_len);
602
   if ( ata_cdbu[h][0] == 0x25 )
603
   {
604
      if ( workrequ->request_bufflen > 8 )
605
      {
606
         workrequ->request_bufflen=0x08;
607
      }
608
   }
609
   if ( ata_cdbu[h][0] == 0x12 )
610
   {
611
      if ( workrequ->request_bufflen > 0x24 )
612
      {
613
         workrequ->request_bufflen = 0x24;
614
         ata_cdbu[h][4]=0x24;
615
      }
616
   }
617
 
618
   tmport=workportu+0x1b;
619
   j=inb(tmport) & 0x0e;
620
   tarid=workrequ->target;
621
   w=1;
622
   w = w << tarid;
623
   if ((w & wide_idu[h]) != 0)
624
   {
625
      j |= 0x01;
626
   }
627
   outb(j,tmport);
628
   tmport=workportu;
629
   outb(workrequ->cmd_len,tmport++);
630
   outb(0x2c,tmport++);
631
   outb(0xcf,tmport++);
632
   for ( i=0 ; i < workrequ->cmd_len ; i++ )
633
   {
634
       outb(ata_cdbu[h][i],tmport++);
635
   }
636
   tmport=workportu+0x0f;
637
   outb(0x00,tmport);
638
   tmport+=0x02;
639
   outb(devspu[h][tarid],tmport++);
640
   if (workrequ->use_sg)
641
   {
642
 
643
     l=0;
644
     sgpnt = (struct scatterlist *) workrequ->request_buffer;
645
     for(i=0; i<workrequ->use_sg; i++)
646
     {
647
       if(sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)
648
       {
649
         panic("Foooooooood fight!");
650
       }
651
       l += sgpnt[i].length;
652
     }
653
   }
654
   else
655
   {
656
     l=workrequ->request_bufflen;
657
   }
658
   outb((unsigned char)(((unsigned char *)(&l))[2]),tmport++);
659
   outb((unsigned char)(((unsigned char *)(&l))[1]),tmport++);
660
   outb((unsigned char)(((unsigned char *)(&l))[0]),tmport++);
661
   j=tarid;
662
   last_lenu[h][j]=l;
663
   tran_lenu[h][j]=0;
664
   if ((j & 0x08) != 0)
665
   {
666
      j=(j & 0x07) | 0x40;
667
   }
668
   if ((ata_cdbu[h][0] == 0x0a) || (ata_cdbu[h][0] == 0x2a) ||
669
       (ata_cdbu[h][0] == 0xaa) || (ata_cdbu[h][0] == 0x15))
670
   {
671
      outb((unsigned char)(j | 0x20),tmport++);
672
   }
673
   else
674
   {
675
      outb(j,tmport++);
676
   }
677
   outb(0x80,tmport);
678
   tmport=workportu + 0x1c;
679
   dirctu[h][tarid]=0;
680
   if ( l == 0 )
681
   {
682
      if ( inb(tmport) == 0 )
683
      {
684
         tmport=workportu+0x18;
685
         outb(0x08,tmport);
686
      }
687
      else
688
      {
689
        last_cmd[h] |= 0x40;
690
      }
691
      in_snd[h]=0;
692
      restore_flags(flags);
693
      return;
694
   }
695
   tmpcip=pciportu[h];
696
   prd=&prd_tableu[h][tarid][0];
697
   prd_posu[h][tarid]=prd;
698
   if (workrequ->use_sg)
699
   {
700
     sgpnt = (struct scatterlist *) workrequ->request_buffer;
701
     i=0;
702
     for(j=0; j<workrequ->use_sg; j++)
703
     {
704
        (unsigned long)(((unsigned long *)(prd))[i >> 1])=(unsigned long)sgpnt[j].address;
705
        (unsigned short int)(((unsigned short int *)(prd))[i+2])=sgpnt[j].length;
706
        (unsigned short int)(((unsigned short int *)(prd))[i+3])=0;
707
        i +=0x04;
708
     }
709
     (unsigned short int)(((unsigned short int *)(prd))[i-1])=0x8000;
710
   }
711
   else
712
   {
713
     bttl=(unsigned long)workrequ->request_buffer;
714
     l=workrequ->request_bufflen;
715
     i=0;
716
     while ( l > 0x10000 )
717
     {
718
        (unsigned short int)(((unsigned short int *)(prd))[i+3])=0x0000;
719
        (unsigned short int)(((unsigned short int *)(prd))[i+2])=0x0000;
720
        (unsigned long)(((unsigned long *)(prd))[i >> 1])=bttl;
721
        l -= 0x10000;
722
        bttl += 0x10000;
723
        i += 0x04;
724
     }
725
     (unsigned short int)(((unsigned short int *)(prd))[i+3])=0x8000;
726
     (unsigned short int)(((unsigned short int *)(prd))[i+2])=l;
727
     (unsigned long)(((unsigned long *)(prd))[i >> 1])=bttl;
728
   }
729
   tmpcip=tmpcip+4;
730
   prdaddru[h][tarid]=(unsigned long)&prd_tableu[h][tarid][0];
731
   outl(prdaddru[h][tarid],tmpcip);
732
   tmpcip=tmpcip-2;
733
   outb(0x06,tmpcip);
734
   outb(0x00,tmpcip);
735
   tmpcip=tmpcip-2;
736
   if ((ata_cdbu[h][0] == 0x0a) || (ata_cdbu[h][0] == 0x2a) ||
737
       (ata_cdbu[h][0] == 0xaa) || (ata_cdbu[h][0] == 0x15))
738
   {
739
      dirctu[h][tarid]=0x20;
740
      if ( inb(tmport) == 0 )
741
      {
742
         tmport=workportu+0x18;
743
         outb(0x08,tmport);
744
         outb(0x01,tmpcip);
745
      }
746
      else
747
      {
748
         last_cmd[h] |= 0x40;
749
      }
750
      in_snd[h]=0;
751
      restore_flags(flags);
752
      return;
753
   }
754
   if ( inb(tmport) == 0 )
755
   {
756
      tmport=workportu+0x18;
757
      outb(0x08,tmport);
758
      outb(0x09,tmpcip);
759
   }
760
   else
761
   {
762
      last_cmd[h] |= 0x40;
763
   }
764
   in_snd[h]=0;
765
   restore_flags(flags);
766
   return;
767
 
768
}
769
 
770
static void internal_done(Scsi_Cmnd * SCpnt)
771
{
772
        SCpnt->SCp.Status++;
773
}
774
 
775
int atp870u_command(Scsi_Cmnd * SCpnt)
776
{
777
 
778
    atp870u_queuecommand(SCpnt, internal_done);
779
 
780
    SCpnt->SCp.Status = 0;
781
    while (!SCpnt->SCp.Status)
782
        barrier();
783
    return SCpnt->result;
784
}
785
 
786
unsigned char fun_scam ( unsigned char host,unsigned short int * val )
787
{
788
    unsigned int  tmport ;
789
    unsigned short int   i,k;
790
    unsigned char     j;
791
 
792
    tmport = ioportu[host]+0x1c;
793
    outw(*val,tmport);
794
FUN_D7:
795
    for ( i=0; i < 10; i++ )          /* stable >= bus settle delay(400 ns)  */
796
    {
797
        k=inw(tmport);
798
        j= (unsigned char)(k >> 8);
799
        if ((k & 0x8000) != 0)        /* DB7 all release?    */
800
        {
801
           goto  FUN_D7;
802
        }
803
    }
804
    *val |= 0x4000;                 /* assert DB6           */
805
    outw(*val,tmport);
806
    *val &= 0xdfff;                 /* assert DB5           */
807
    outw(*val,tmport);
808
FUN_D5:
809
    for ( i=0; i < 10; i++ )         /* stable >= bus settle delay(400 ns) */
810
    {
811
       if ((inw(tmport) & 0x2000) != 0)   /* DB5 all release?    */
812
       {
813
          goto  FUN_D5;
814
       }
815
    }
816
    *val |= 0x8000;                  /* no DB4-0, assert DB7    */
817
    *val &= 0xe0ff;
818
    outw(*val,tmport);
819
    *val &= 0xbfff;                  /* release DB6             */
820
    outw(*val,tmport);
821
FUN_D6:
822
    for ( i=0; i < 10; i++ )          /* stable >= bus settle delay(400 ns)  */
823
    {
824
       if ((inw(tmport) & 0x4000) != 0)   /* DB6 all release?  */
825
       {
826
          goto  FUN_D6;
827
       }
828
    }
829
 
830
    return j;
831
}
832
 
833
void tscam( unsigned char host )
834
{
835
 
836
    unsigned int  tmport ;
837
    unsigned char  i,j,k;
838
    unsigned long  n;
839
    unsigned short int  m,assignid_map,val;
840
    unsigned char  mbuf[33],quintet[2];
841
    static unsigned char g2q_tab[8]={ 0x38,0x31,0x32,0x2b,0x34,0x2d,0x2e,0x27 };
842
 
843
 
844
    for ( i=0; i < 0x10; i++ )
845
    {
846
        mydlyu(0xffff);
847
    }
848
 
849
    tmport = ioportu[host]+1;
850
    outb(0x08,tmport++);
851
    outb(0x7f,tmport);
852
    tmport = ioportu[host]+0x11;
853
    outb(0x20,tmport);
854
 
855
    if ((scam_on[host] & 0x40) == 0)
856
    {
857
       return;
858
    }
859
 
860
    m=1;
861
    m <<= host_idu[host];
862
    j=16;
863
    if ( chip_veru[host] < 4 )
864
    {
865
       m |= 0xff00;
866
       j=8;
867
    }
868
    assignid_map=m;
869
    tmport = ioportu[host]+0x02;
870
    outb(0x02,tmport++);        /* 2*2=4ms,3EH 2/32*3E=3.9ms */
871
    outb(0,tmport++);
872
    outb(0,tmport++);
873
    outb(0,tmport++);
874
    outb(0,tmport++);
875
    outb(0,tmport++);
876
    outb(0,tmport++);
877
 
878
    for ( i = 0 ; i < j ; i ++ )
879
    {
880
        m=1;
881
        m=m<<i;
882
        if ( ( m & assignid_map ) != 0 )
883
        {
884
           continue;
885
        }
886
    tmport = ioportu[host]+0x0f;
887
    outb(0,tmport++);
888
    tmport += 0x02;
889
    outb(0,tmport++);
890
    outb(0,tmport++);
891
    outb(0,tmport++);
892
    if ( i > 7 )
893
    {
894
       k=(i & 0x07) | 0x40;
895
    }
896
    else
897
    {
898
       k=i;
899
    }
900
    outb(k,tmport++);
901
    tmport = ioportu[host]+0x1b;
902
    if ( chip_veru[host] == 4 )
903
    {
904
       outb((unsigned char)((inb(tmport) & 0x0e) | 0x01),tmport);
905
    }
906
    else
907
    {
908
       outb((unsigned char)(inb(tmport) & 0x0e),tmport);
909
    }
910
wait_rdyok:
911
    tmport = ioportu[host]+0x18;
912
    outb(0x09,tmport);
913
    tmport += 0x07;
914
 
915
    while ((inb(tmport) & 0x80) == 0x00);
916
    tmport -= 0x08;
917
    k=inb(tmport);
918
    if ( k != 0x16 )
919
    {
920
       if ((k == 0x85) || (k == 0x42))
921
       {
922
          continue;
923
       }
924
       tmport = ioportu[host]+0x10;
925
       outb(0x41,tmport);
926
       goto wait_rdyok;
927
    }
928
    assignid_map |= m;
929
 
930
    }
931
    tmport = ioportu[host]+0x02;
932
    outb(0x7f,tmport);
933
    tmport = ioportu[host]+0x1b;
934
    outb(0x02,tmport);
935
 
936
    outb(0,0x80);
937
 
938
    val=0x0080;      /* bsy  */
939
    tmport = ioportu[host]+0x1c;
940
    outw(val,tmport);
941
    val |=0x0040;    /* sel  */
942
    outw(val,tmport);
943
    val |=0x0004;    /* msg  */
944
    outw(val,tmport);
945
    inb(0x80);                /* 2 deskew delay(45ns*2=90ns) */
946
    val &=0x007f;    /* no bsy  */
947
    outw(val,tmport);
948
    mydlyu(0xffff);  /* recommanded SCAM selection response time */
949
    mydlyu(0xffff);
950
    val &=0x00fb;    /* after 1ms no msg */
951
    outw(val,tmport);
952
wait_nomsg:
953
    if ((inb(tmport) & 0x04) != 0)
954
    {
955
       goto wait_nomsg;
956
    }
957
    outb(1,0x80);
958
    mydlyu(100);
959
    for ( n=0; n < 0x30000; n++ )
960
    {
961
        if ((inb(tmport) & 0x80) != 0)      /* bsy ? */
962
        {
963
           goto wait_io;
964
        }
965
    }
966
    goto  TCM_SYNC;
967
wait_io:
968
    for ( n=0; n < 0x30000; n++ )
969
    {
970
        if ((inb(tmport) & 0x81) == 0x0081)
971
        {
972
           goto wait_io1;
973
        }
974
    }
975
    goto  TCM_SYNC;
976
wait_io1:
977
    inb(0x80);
978
    val |=0x8003;    /* io,cd,db7  */
979
    outw(val,tmport);
980
    inb(0x80);
981
    val &=0x00bf;    /* no sel     */
982
    outw(val,tmport);
983
    outb(2,0x80);
984
TCM_SYNC:
985
    mydlyu(0x800);
986
    if ((inb(tmport) & 0x80) == 0x00)    /* bsy ? */
987
    {
988
       outw(0,tmport--);
989
       outb(0,tmport);
990
       tmport=ioportu[host] + 0x15;
991
       outb(0,tmport);
992
       tmport += 0x03;
993
       outb(0x09,tmport);
994
       tmport += 0x07;
995
       while ((inb(tmport) & 0x80) == 0);
996
       tmport -= 0x08;
997
       inb(tmport);
998
       return;
999
    }
1000
 
1001
    val &= 0x00ff;               /* synchronization  */
1002
    val |= 0x3f00;
1003
    fun_scam(host,&val);
1004
    outb(3,0x80);
1005
    val &= 0x00ff;               /* isolation        */
1006
    val |= 0x2000;
1007
    fun_scam(host,&val);
1008
    outb(4,0x80);
1009
    i=8;
1010
    j=0;
1011
TCM_ID:
1012
    if ((inw(tmport) & 0x2000) == 0)
1013
    {
1014
       goto TCM_ID;
1015
    }
1016
    outb(5,0x80);
1017
    val &= 0x00ff;               /* get ID_STRING */
1018
    val |= 0x2000;
1019
    k=fun_scam(host,&val);
1020
    if ((k & 0x03) == 0)
1021
    {
1022
       goto TCM_5;
1023
    }
1024
    mbuf[j] <<= 0x01;
1025
    mbuf[j] &= 0xfe;
1026
    if ((k & 0x02) != 0)
1027
    {
1028
       mbuf[j] |= 0x01;
1029
    }
1030
    i--;
1031
    if ( i > 0 )
1032
    {
1033
       goto TCM_ID;
1034
    }
1035
    j++;
1036
    i=8;
1037
    goto TCM_ID;
1038
 
1039
TCM_5:                       /* isolation complete..  */
1040
/*    mbuf[32]=0;
1041
    printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1042
    i=15;
1043
    j=mbuf[0];
1044
    if ((j & 0x20) != 0)     /* bit5=1:ID upto 7      */
1045
    {
1046
       i=7;
1047
    }
1048
    if ((j & 0x06) == 0)     /* IDvalid?       */
1049
    {
1050
       goto  G2Q5;
1051
    }
1052
    k=mbuf[1];
1053
small_id:
1054
    m=1;
1055
    m <<= k;
1056
    if ((m & assignid_map) == 0)
1057
    {
1058
       goto G2Q_QUIN;
1059
    }
1060
    if ( k > 0 )
1061
    {
1062
       k--;
1063
       goto small_id;
1064
    }
1065
G2Q5:                         /* srch from max acceptable ID#  */
1066
    k=i;                      /* max acceptable ID#            */
1067
G2Q_LP:
1068
    m=1;
1069
    m <<= k;
1070
    if ((m & assignid_map) == 0)
1071
    {
1072
       goto G2Q_QUIN;
1073
    }
1074
    if ( k > 0 )
1075
    {
1076
       k--;
1077
       goto G2Q_LP;
1078
    }
1079
G2Q_QUIN:                     /* k=binID#,       */
1080
    assignid_map |= m;
1081
    if ( k < 8 )
1082
    {
1083
       quintet[0]=0x38;       /* 1st dft ID<8     */
1084
    }
1085
    else
1086
    {
1087
       quintet[0]=0x31;       /* 1st  ID>=8       */
1088
    }
1089
    k &= 0x07;
1090
    quintet[1]=g2q_tab[k];
1091
 
1092
    val &= 0x00ff;             /* AssignID 1stQuintet,AH=001xxxxx  */
1093
    m=quintet[0] << 8;
1094
    val |= m;
1095
    fun_scam(host,&val);
1096
    val &= 0x00ff;             /* AssignID 2ndQuintet,AH=001xxxxx */
1097
    m=quintet[1] << 8;
1098
    val |= m;
1099
    fun_scam(host,&val);
1100
 
1101
    goto TCM_SYNC;
1102
 
1103
}
1104
 
1105
void is870(unsigned long host,unsigned int wkport )
1106
{
1107
    unsigned int  tmport ;
1108
    unsigned char i,j,k,rmb;
1109
    unsigned short int m;
1110
    static unsigned char mbuf[512];
1111
    static unsigned char satn[9] = { 0,0,0,0,0,0,0,6,6 };
1112
    static unsigned char inqd[9] = { 0x12,0,0,0,0x24,0,0,0x24,6 };
1113
    static unsigned char synn[6] = { 0x80,1,3,1,0x19,0x0e };
1114
    static unsigned char synu[6] = { 0x80,1,3,1,0x0c,0x0e };
1115
    static unsigned char synw[6] = { 0x80,1,3,1,0x0c,0x07 };
1116
    static unsigned char wide[6] = { 0x80,1,2,3,1,0 };
1117
 
1118
    sync_idu=0;
1119
    tmport=wkport+0x3a;
1120
    outb((unsigned char)(inb(tmport) | 0x10),tmport);
1121
 
1122
    for ( i = 0 ; i < 16 ; i ++ )
1123
    {
1124
        if ((chip_veru[host] != 4) && (i > 7))
1125
        {
1126
           break;
1127
        }
1128
        m=1;
1129
        m=m<<i;
1130
        if ( ( m & active_idu[host] ) != 0 )
1131
        {
1132
           continue;
1133
        }
1134
        if ( i == host_idu[host] )
1135
        {
1136
           printk("         ID: %2d  Host Adapter\n",host_idu[host]);
1137
           continue;
1138
        }
1139
        if ( chip_veru[host] == 4 )
1140
        {
1141
           tmport=wkport+0x1b;
1142
           j=(inb(tmport) & 0x0e) | 0x01;
1143
           outb(j,tmport);
1144
        }
1145
    tmport=wkport+1;
1146
    outb(0x08,tmport++);
1147
    outb(0x7f,tmport++);
1148
    outb(satn[0],tmport++);
1149
    outb(satn[1],tmport++);
1150
    outb(satn[2],tmport++);
1151
    outb(satn[3],tmport++);
1152
    outb(satn[4],tmport++);
1153
    outb(satn[5],tmport++);
1154
    tmport+=0x06;
1155
    outb(0,tmport);
1156
    tmport+=0x02;
1157
    outb(devspu[host][i],tmport++);
1158
    outb(0,tmport++);
1159
    outb(satn[6],tmport++);
1160
    outb(satn[7],tmport++);
1161
    j=i;
1162
    if ((j & 0x08) != 0)
1163
    {
1164
       j=(j & 0x07) | 0x40;
1165
    }
1166
    outb(j,tmport);
1167
    tmport+=0x03;
1168
    outb(satn[8],tmport);
1169
    tmport+=0x07;
1170
 
1171
    while ((inb(tmport) & 0x80) == 0x00);
1172
    tmport-=0x08;
1173
    if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e))
1174
    {
1175
       continue;
1176
    }
1177
    while ( inb(tmport) != 0x8e );
1178
    active_idu[host] |= m;
1179
 
1180
    tmport=wkport+0x10;
1181
    outb(0x30,tmport);
1182
    tmport=wkport+0x04;
1183
    outb(0x00,tmport);
1184
 
1185
phase_cmd:
1186
    tmport=wkport+0x18;
1187
    outb(0x08,tmport);
1188
    tmport+=0x07;
1189
    while ((inb(tmport) & 0x80) == 0x00);
1190
    tmport-=0x08;
1191
    j=inb(tmport);
1192
    if ( j != 0x16 )
1193
    {
1194
       tmport=wkport+0x10;
1195
       outb(0x41,tmport);
1196
       goto phase_cmd;
1197
    }
1198
sel_ok:
1199
       tmport=wkport+3;
1200
       outb(inqd[0],tmport++);
1201
       outb(inqd[1],tmport++);
1202
       outb(inqd[2],tmport++);
1203
       outb(inqd[3],tmport++);
1204
       outb(inqd[4],tmport++);
1205
       outb(inqd[5],tmport);
1206
       tmport+=0x07;
1207
       outb(0,tmport);
1208
       tmport+=0x02;
1209
       outb(devspu[host][i],tmport++);
1210
       outb(0,tmport++);
1211
       outb(inqd[6],tmport++);
1212
       outb(inqd[7],tmport++);
1213
       tmport+=0x03;
1214
       outb(inqd[8],tmport);
1215
       tmport+=0x07;
1216
       while ((inb(tmport) & 0x80) == 0x00);
1217
       tmport-=0x08;
1218
       if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e))
1219
       {
1220
          continue;
1221
       }
1222
       while ( inb(tmport) != 0x8e );
1223
       if ( chip_veru[host] == 4 )
1224
       {
1225
          tmport=wkport+0x1b;
1226
          j=inb(tmport) & 0x0e;
1227
          outb(j,tmport);
1228
       }
1229
       tmport=wkport+0x18;
1230
       outb(0x08,tmport);
1231
       tmport += 0x07;
1232
       j=0;
1233
rd_inq_data:
1234
       k=inb(tmport);
1235
       if ((k & 0x01) != 0 )
1236
       {
1237
          tmport-=0x06;
1238
          mbuf[j++]=inb(tmport);
1239
          tmport+=0x06;
1240
          goto rd_inq_data;
1241
       }
1242
       if ((k & 0x80) == 0 )
1243
       {
1244
          goto rd_inq_data;
1245
       }
1246
       tmport-=0x08;
1247
       j=inb(tmport);
1248
       if ( j == 0x16 )
1249
       {
1250
          goto inq_ok;
1251
       }
1252
    tmport=wkport+0x10;
1253
    outb(0x46,tmport);
1254
    tmport+=0x02;
1255
    outb(0,tmport++);
1256
    outb(0,tmport++);
1257
    outb(0,tmport++);
1258
    tmport+=0x03;
1259
    outb(0x08,tmport);
1260
    tmport+=0x07;
1261
    while ((inb(tmport) & 0x80) == 0x00);
1262
    tmport-=0x08;
1263
    if (inb(tmport) != 0x16)
1264
    {
1265
       goto sel_ok;
1266
    }
1267
inq_ok:
1268
     mbuf[36]=0;
1269
     printk("         ID: %2d  %s\n",i,&mbuf[8]);
1270
     devtypeu[host][i]=mbuf[0];
1271
     rmb=mbuf[1];
1272
     if ( chip_veru[host] != 4 )
1273
     {
1274
        goto not_wide;
1275
     }
1276
     if ((mbuf[7] & 0x60) == 0)
1277
     {
1278
        goto not_wide;
1279
     }
1280
     if ((global_map[host] & 0x20) == 0)
1281
     {
1282
        goto not_wide;
1283
     }
1284
     tmport=wkport+0x1b;
1285
     j=(inb(tmport) & 0x0e) | 0x01;
1286
     outb(j,tmport);
1287
    tmport=wkport+3;
1288
    outb(satn[0],tmport++);
1289
    outb(satn[1],tmport++);
1290
    outb(satn[2],tmport++);
1291
    outb(satn[3],tmport++);
1292
    outb(satn[4],tmport++);
1293
    outb(satn[5],tmport++);
1294
    tmport+=0x06;
1295
    outb(0,tmport);
1296
    tmport+=0x02;
1297
    outb(devspu[host][i],tmport++);
1298
    outb(0,tmport++);
1299
    outb(satn[6],tmport++);
1300
    outb(satn[7],tmport++);
1301
    tmport+=0x03;
1302
    outb(satn[8],tmport);
1303
    tmport+=0x07;
1304
 
1305
    while ((inb(tmport) & 0x80) == 0x00);
1306
    tmport-=0x08;
1307
    if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e))
1308
    {
1309
       continue;
1310
    }
1311
    while ( inb(tmport) != 0x8e );
1312
try_wide:
1313
    j=0;
1314
    tmport=wkport+0x14;
1315
    outb(0x05,tmport);
1316
    tmport += 0x04;
1317
    outb(0x20,tmport);
1318
    tmport+=0x07;
1319
 
1320
    while ((inb(tmport) & 0x80) == 0 )
1321
    {
1322
       if ((inb(tmport) & 0x01) != 0 )
1323
       {
1324
          tmport-=0x06;
1325
          outb(wide[j++],tmport);
1326
          tmport+=0x06;
1327
       }
1328
    }
1329
    tmport-=0x08;
1330
    while ((inb(tmport) & 0x80) == 0x00);
1331
    j=inb(tmport) & 0x0f;
1332
    if ( j == 0x0f )
1333
    {
1334
       goto widep_in;
1335
    }
1336
    if ( j == 0x0a )
1337
    {
1338
       goto widep_cmd;
1339
    }
1340
    if ( j == 0x0e )
1341
    {
1342
       goto try_wide;
1343
    }
1344
    continue;
1345
widep_out:
1346
    tmport=wkport+0x18;
1347
    outb(0x20,tmport);
1348
    tmport+=0x07;
1349
    while ((inb(tmport) & 0x80) == 0 )
1350
    {
1351
        if ((inb(tmport) & 0x01) != 0 )
1352
        {
1353
           tmport-=0x06;
1354
           outb(0,tmport);
1355
           tmport+=0x06;
1356
        }
1357
    }
1358
    tmport-=0x08;
1359
    j=inb(tmport) & 0x0f;
1360
    if ( j == 0x0f )
1361
    {
1362
       goto widep_in;
1363
    }
1364
    if ( j == 0x0a )
1365
    {
1366
       goto widep_cmd;
1367
    }
1368
    if ( j == 0x0e )
1369
    {
1370
       goto widep_out;
1371
    }
1372
    continue;
1373
widep_in:
1374
    tmport=wkport+0x14;
1375
    outb(0xff,tmport);
1376
    tmport += 0x04;
1377
    outb(0x20,tmport);
1378
    tmport+=0x07;
1379
    k=0;
1380
widep_in1:
1381
    j=inb(tmport);
1382
    if ((j & 0x01) != 0)
1383
    {
1384
       tmport-=0x06;
1385
       mbuf[k++]=inb(tmport);
1386
       tmport+=0x06;
1387
       goto widep_in1;
1388
    }
1389
    if ((j & 0x80) == 0x00)
1390
    {
1391
       goto widep_in1;
1392
    }
1393
    tmport-=0x08;
1394
    j=inb(tmport) & 0x0f;
1395
    if ( j == 0x0f )
1396
    {
1397
       goto widep_in;
1398
    }
1399
    if ( j == 0x0a )
1400
    {
1401
       goto widep_cmd;
1402
    }
1403
    if ( j == 0x0e )
1404
    {
1405
       goto widep_out;
1406
    }
1407
    continue;
1408
widep_cmd:
1409
    tmport=wkport+0x10;
1410
    outb(0x30,tmport);
1411
    tmport=wkport+0x14;
1412
    outb(0x00,tmport);
1413
    tmport+=0x04;
1414
    outb(0x08,tmport);
1415
    tmport+=0x07;
1416
    while ((inb(tmport) & 0x80) == 0x00);
1417
    tmport-=0x08;
1418
    j=inb(tmport);
1419
    if ( j != 0x16 )
1420
    {
1421
       if ( j == 0x4e )
1422
       {
1423
          goto widep_out;
1424
       }
1425
       continue;
1426
    }
1427
    if ( mbuf[0] != 0x01 )
1428
    {
1429
       goto not_wide;
1430
    }
1431
    if ( mbuf[1] != 0x02 )
1432
    {
1433
       goto not_wide;
1434
    }
1435
    if ( mbuf[2] != 0x03 )
1436
    {
1437
       goto not_wide;
1438
    }
1439
    if ( mbuf[3] != 0x01 )
1440
    {
1441
       goto not_wide;
1442
    }
1443
    m=1;
1444
    m = m << i;
1445
    wide_idu[host] |= m;
1446
not_wide:
1447
    if ((devtypeu[host][i] == 0x00) || (devtypeu[host][i] == 0x07))
1448
    {
1449
       goto set_sync;
1450
    }
1451
    continue;
1452
set_sync:
1453
    tmport=wkport+0x1b;
1454
    j=inb(tmport) & 0x0e;
1455
    if ((m & wide_idu[host]) != 0 )
1456
    {
1457
       j |= 0x01;
1458
    }
1459
    outb(j,tmport);
1460
    tmport=wkport+3;
1461
    outb(satn[0],tmport++);
1462
    outb(satn[1],tmport++);
1463
    outb(satn[2],tmport++);
1464
    outb(satn[3],tmport++);
1465
    outb(satn[4],tmport++);
1466
    outb(satn[5],tmport++);
1467
    tmport+=0x06;
1468
    outb(0,tmport);
1469
    tmport+=0x02;
1470
    outb(devspu[host][i],tmport++);
1471
    outb(0,tmport++);
1472
    outb(satn[6],tmport++);
1473
    outb(satn[7],tmport++);
1474
    tmport+=0x03;
1475
    outb(satn[8],tmport);
1476
    tmport+=0x07;
1477
 
1478
    while ((inb(tmport) & 0x80) == 0x00);
1479
    tmport-=0x08;
1480
    if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e))
1481
    {
1482
       continue;
1483
    }
1484
    while ( inb(tmport) != 0x8e);
1485
try_sync:
1486
    j=0;
1487
    tmport=wkport+0x14;
1488
    outb(0x06,tmport);
1489
    tmport += 0x04;
1490
    outb(0x20,tmport);
1491
    tmport+=0x07;
1492
 
1493
    while ((inb(tmport) & 0x80) == 0 )
1494
    {
1495
       if ((inb(tmport) & 0x01) != 0 )
1496
       {
1497
          tmport-=0x06;
1498
          if ( rmb != 0 )
1499
          {
1500
             outb(synn[j++],tmport);
1501
          }
1502
          else
1503
          {
1504
             if ((m & wide_idu[host]) != 0)
1505
             {
1506
                outb(synw[j++],tmport);
1507
             }
1508
             else
1509
             {
1510
                if ((m & ultra_map[host]) != 0)
1511
                {
1512
                   outb(synu[j++],tmport);
1513
                }
1514
                else
1515
                {
1516
                   outb(synn[j++],tmport);
1517
                }
1518
             }
1519
          }
1520
          tmport+=0x06;
1521
       }
1522
    }
1523
    tmport-=0x08;
1524
    while ((inb(tmport) & 0x80) == 0x00);
1525
    j=inb(tmport) & 0x0f;
1526
    if ( j == 0x0f )
1527
    {
1528
       goto phase_ins;
1529
    }
1530
    if ( j == 0x0a )
1531
    {
1532
       goto phase_cmds;
1533
    }
1534
    if ( j == 0x0e )
1535
    {
1536
       goto try_sync;
1537
    }
1538
    continue;
1539
phase_outs:
1540
    tmport=wkport+0x18;
1541
    outb(0x20,tmport);
1542
    tmport+=0x07;
1543
    while ((inb(tmport) & 0x80) == 0x00)
1544
    {
1545
      if ((inb(tmport) & 0x01) != 0x00)
1546
      {
1547
         tmport-=0x06;
1548
         outb(0x00,tmport);
1549
         tmport+=0x06;
1550
      }
1551
    }
1552
    tmport-=0x08;
1553
    j=inb(tmport);
1554
    if ( j == 0x85 )
1555
    {
1556
       goto tar_dcons;
1557
    }
1558
    j &= 0x0f;
1559
    if ( j == 0x0f )
1560
    {
1561
       goto phase_ins;
1562
    }
1563
    if ( j == 0x0a )
1564
    {
1565
       goto phase_cmds;
1566
    }
1567
    if ( j == 0x0e )
1568
    {
1569
       goto phase_outs;
1570
    }
1571
    continue;
1572
phase_ins:
1573
    tmport=wkport+0x14;
1574
    outb(0xff,tmport);
1575
    tmport += 0x04;
1576
    outb(0x20,tmport);
1577
    tmport+=0x07;
1578
    k=0;
1579
phase_ins1:
1580
    j=inb(tmport);
1581
    if ((j & 0x01) != 0x00)
1582
    {
1583
       tmport-=0x06;
1584
       mbuf[k++]=inb(tmport);
1585
       tmport+=0x06;
1586
       goto phase_ins1;
1587
    }
1588
    if ((j & 0x80) == 0x00)
1589
    {
1590
       goto phase_ins1;
1591
    }
1592
    tmport-=0x08;
1593
    while ((inb(tmport) & 0x80) == 0x00);
1594
    j=inb(tmport);
1595
    if ( j == 0x85 )
1596
    {
1597
       goto tar_dcons;
1598
    }
1599
    j &= 0x0f;
1600
    if ( j == 0x0f )
1601
    {
1602
       goto phase_ins;
1603
    }
1604
    if ( j == 0x0a )
1605
    {
1606
       goto phase_cmds;
1607
    }
1608
    if ( j == 0x0e )
1609
    {
1610
       goto phase_outs;
1611
    }
1612
    continue;
1613
phase_cmds:
1614
    tmport=wkport+0x10;
1615
    outb(0x30,tmport);
1616
tar_dcons:
1617
    tmport=wkport+0x14;
1618
    outb(0x00,tmport);
1619
    tmport+=0x04;
1620
    outb(0x08,tmport);
1621
    tmport+=0x07;
1622
    while ((inb(tmport) & 0x80) == 0x00);
1623
    tmport-=0x08;
1624
    j=inb(tmport);
1625
    if ( j != 0x16 )
1626
    {
1627
       continue;
1628
    }
1629
    if ( mbuf[0] != 0x01 )
1630
    {
1631
       continue;
1632
    }
1633
    if ( mbuf[1] != 0x03 )
1634
    {
1635
       continue;
1636
    }
1637
    if ( mbuf[4] == 0x00 )
1638
    {
1639
       continue;
1640
    }
1641
    if ( mbuf[3] > 0x64 )
1642
    {
1643
       continue;
1644
    }
1645
    if ( mbuf[4] > 0x0c )
1646
    {
1647
       mbuf[4]=0x0c;
1648
    }
1649
    devspu[host][i] = mbuf[4];
1650
    if ((mbuf[3] < 0x0d) && (rmb == 0))
1651
    {
1652
       j=0xa0;
1653
       goto set_syn_ok;
1654
    }
1655
    if ( mbuf[3] < 0x1a )
1656
    {
1657
       j=0x20;
1658
       goto set_syn_ok;
1659
    }
1660
    if ( mbuf[3] < 0x33 )
1661
    {
1662
       j=0x40;
1663
       goto set_syn_ok;
1664
    }
1665
    if ( mbuf[3] < 0x4c )
1666
    {
1667
       j=0x50;
1668
       goto set_syn_ok;
1669
    }
1670
    j=0x60;
1671
set_syn_ok:
1672
    devspu[host][i] = (devspu[host][i] & 0x0f) | j;
1673
   }
1674
   tmport=wkport+0x3a;
1675
   outb((unsigned char)(inb(tmport) & 0xef),tmport);
1676
}
1677
 
1678
/* return non-zero on detection */
1679
int atp870u_detect(Scsi_Host_Template * tpnt)
1680
{
1681
    unsigned char irq,h,k;
1682
    unsigned long flags;
1683
    unsigned int base_io,error,tmport;
1684
    unsigned short index = 0;
1685
    unsigned char pci_bus[3], pci_device_fn[3], chip_ver[3],host_id;
1686
    struct Scsi_Host * shpnt = NULL;
1687
    int count = 0;
1688
    static unsigned short devid[7]={0x8002,0x8010,0x8020,0x8030,0x8040,0x8050,0};
1689
 
1690
    printk("aec671x_detect: \n");
1691
    if (!pcibios_present())
1692
    {
1693
       printk("   NO BIOS32 SUPPORT.\n");
1694
       return count;
1695
    }
1696
 
1697
    tpnt->proc_dir = &proc_scsi_atp870u;
1698
 
1699
    for ( h = 0 ; h < 2 ; h++ )
1700
    {
1701
      active_idu[h]=0;
1702
      wide_idu[h]=0;
1703
      host_idu[h]=0x07;
1704
      quhdu[h]=0;
1705
      quendu[h]=0;
1706
      pci_bus[h]=0;
1707
      pci_device_fn[h]=0xff;
1708
      chip_ver[h]=0;
1709
      last_cmd[h]=0xff;
1710
      in_snd[h]=0;
1711
      in_int[h]=0;
1712
      for ( k = 0 ; k < qcnt ; k++ )
1713
      {
1714
          querequ[h][k]=0;
1715
      }
1716
      for ( k = 0 ; k < 16 ; k++ )
1717
      {
1718
          curr_req[h][k]=0;
1719
      }
1720
    }
1721
    h=0;
1722
    while ( devid[h] != 0 )
1723
    {
1724
       if (pcibios_find_device(0x1191,devid[h],index,&pci_bus[2],&pci_device_fn[2]))
1725
       {
1726
          h++;
1727
          index=0;
1728
          continue;
1729
       }
1730
       chip_ver[2]=0;
1731
       if ( devid[h] == 0x8002 )
1732
       {
1733
          error = pcibios_read_config_byte(pci_bus[2],pci_device_fn[2],0x08,&chip_ver[2]);
1734
          if ( chip_ver[2] < 2 )
1735
          {
1736
             goto nxt_devfn;
1737
          }
1738
       }
1739
       if ( devid[h] == 0x8010 )
1740
       {
1741
          chip_ver[2]=0x04;
1742
       }
1743
       if ( pci_device_fn[2] < pci_device_fn[0] )
1744
       {
1745
          pci_bus[1]=pci_bus[0];
1746
          pci_device_fn[1]=pci_device_fn[0];
1747
          chip_ver[1]=chip_ver[0];
1748
          pci_bus[0]=pci_bus[2];
1749
          pci_device_fn[0]=pci_device_fn[2];
1750
          chip_ver[0]=chip_ver[2];
1751
       }
1752
       else if ( pci_device_fn[2] < pci_device_fn[1] )
1753
       {
1754
          pci_bus[1]=pci_bus[2];
1755
          pci_device_fn[1]=pci_device_fn[2];
1756
          chip_ver[1]=chip_ver[2];
1757
       }
1758
nxt_devfn:
1759
       index++;
1760
       if ( index > 3 )
1761
       {
1762
          index=0;
1763
          h++;
1764
       }
1765
    }
1766
    for ( h=0; h < 2; h++ )
1767
    {
1768
    if ( pci_device_fn[h] == 0xff )
1769
    {
1770
       return count;
1771
    }
1772
    /* Found an atp870u/w. */
1773
    error = pcibios_read_config_dword(pci_bus[h],pci_device_fn[h],0x10,&base_io);
1774
    error += pcibios_read_config_byte(pci_bus[h],pci_device_fn[h],0x3c,&irq);
1775
    error += pcibios_read_config_byte(pci_bus[h],pci_device_fn[h],0x49,&host_id);
1776
 
1777
    base_io &= 0xfffffff8;
1778
    printk("   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.\n"
1779
                             ,h,base_io,irq);
1780
    ioportu[h]=base_io;
1781
    pciportu[h]=base_io + 0x20;
1782
    irqnumu[h]=irq;
1783
    host_id &= 0x07;
1784
    host_idu[h]=host_id;
1785
    chip_veru[h]=chip_ver[h];
1786
 
1787
    tmport=base_io+0x22;
1788
    scam_on[h]=inb(tmport);
1789
    tmport += 0x0b;
1790
    global_map[h]=inb(tmport++);
1791
    ultra_map[h]=inw(tmport);
1792
    if ( ultra_map[h] == 0 )
1793
    {
1794
       scam_on[h]=0x00;
1795
       global_map[h]=0x20;
1796
       ultra_map[h]=0xffff;
1797
    }
1798
 
1799
    shpnt = scsi_register(tpnt,4);
1800
 
1801
    save_flags(flags);
1802
    cli();
1803
    if (request_irq(irq,atp870u_intr_handle, 0, "atp870u", NULL))
1804
    {
1805
       printk("Unable to allocate IRQ for Acard controller.\n");
1806
       goto unregister;
1807
    }
1808
 
1809
    tmport=base_io+0x3a;
1810
    k=(inb(tmport) & 0xf3) | 0x10;
1811
    outb(k,tmport);
1812
    outb((k & 0xdf),tmport);
1813
    mydlyu(0x8000);
1814
    outb(k,tmport);
1815
    mydlyu(0x8000);
1816
    tmport=base_io;
1817
    outb((host_id | 0x08),tmport);
1818
    tmport += 0x18;
1819
    outb(0,tmport);
1820
    tmport += 0x07;
1821
    while ((inb(tmport) & 0x80) == 0);
1822
    tmport -= 0x08;
1823
    inb(tmport);
1824
    tmport = base_io +1;
1825
    outb(8,tmport++);
1826
    outb(0x7f,tmport);
1827
    tmport = base_io + 0x11;
1828
    outb(0x20,tmport);
1829
 
1830
    tscam(h);
1831
    is870(h,base_io);
1832
    tmport=base_io+0x3a;
1833
    outb((inb(tmport) & 0xef),tmport);
1834
 
1835
    atp_host[h] = shpnt;
1836
    if ( chip_ver[h] == 4 )
1837
    {
1838
       shpnt->max_id = 16;
1839
    }
1840
    shpnt->this_id = host_id;
1841
    shpnt->unique_id = base_io;
1842
    shpnt->io_port = base_io;
1843
    shpnt->n_io_port = 0x40;  /* Number of bytes of I/O space used */
1844
    shpnt->irq = irq;
1845
    restore_flags(flags);
1846
    request_region(base_io, 0x40,"atp870u");  /* Register the IO ports that we use */
1847
    count++;
1848
    index++;
1849
    continue;
1850
unregister:
1851
    scsi_unregister(shpnt);
1852
    restore_flags(flags);
1853
    index++;
1854
    continue;
1855
    }
1856
 
1857
    return count;
1858
}
1859
 
1860
/* The abort command does not leave the device in a clean state where
1861
   it is available to be used again.  Until this gets worked out, we will
1862
   leave it commented out.  */
1863
 
1864
int atp870u_abort(Scsi_Cmnd * SCpnt)
1865
{
1866
    unsigned char h,j;
1867
    unsigned int  tmport;
1868
/*    printk(" atp870u_abort: \n");   */
1869
    for ( h=0; h <= admaxu; h++ )
1870
    {
1871
        if ( SCpnt->host == atp_host[h] )
1872
        {
1873
           goto find_adp;
1874
        }
1875
    }
1876
    panic("Abort host not found !");
1877
find_adp:
1878
    printk(" workingu=%x last_cmd=%x ",workingu[h],last_cmd[h]);
1879
    printk(" quhdu=%x quendu=%x ",quhdu[h],quendu[h]);
1880
    tmport=ioportu[h];
1881
    for ( j=0; j < 0x17; j++)
1882
    {
1883
        printk(" r%2x=%2x",j,inb(tmport++));
1884
    }
1885
    tmport += 0x05;
1886
    printk(" r1c=%2x",inb(tmport));
1887
    tmport += 0x03;
1888
    printk(" r1f=%2x in_snd=%2x ",inb(tmport),in_snd[h]);
1889
    tmport++;
1890
    printk(" r20=%2x",inb(tmport));
1891
    tmport += 0x02;
1892
    printk(" r22=%2x \n",inb(tmport));
1893
    return (SCSI_ABORT_SNOOZE);
1894
}
1895
 
1896
int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
1897
{
1898
    unsigned char h;
1899
    /*
1900
     * See if a bus reset was suggested.
1901
     */
1902
/*    printk("atp870u_reset: \n");    */
1903
    for( h=0; h <= admaxu; h++ )
1904
    {
1905
       if ( SCpnt->host == atp_host[h] )
1906
       {
1907
          goto find_host;
1908
       }
1909
    }
1910
    panic("Reset bus host not found !");
1911
find_host:
1912
/*    SCpnt->result = 0x00080000;
1913
    SCpnt->scsi_done(SCpnt);
1914
    workingu[h]=0;
1915
    quhdu[h]=0;
1916
    quendu[h]=0;
1917
    return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);  */
1918
    return (SCSI_RESET_SNOOZE);
1919
}
1920
 
1921
const char *
1922
atp870u_info(struct Scsi_Host *notused)
1923
{
1924
  static char buffer[128];
1925
 
1926
  strcpy(buffer, "ACARD AEC-6710/6712 PCI Ultra/W SCSI-3 Adapter Driver V1.0 ");
1927
 
1928
  return buffer;
1929
}
1930
 
1931
int
1932
atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
1933
{
1934
  return (-ENOSYS);  /* Currently this is a no-op */
1935
}
1936
 
1937
#define BLS buffer + len + size
1938
int
1939
atp870u_proc_info(char *buffer, char **start, off_t offset, int length,
1940
    int hostno, int inout)
1941
{
1942
  struct Scsi_Host *HBAptr;
1943
  static u8 buff[512];
1944
  int   i;
1945
  int   size = 0;
1946
  int   len = 0;
1947
  off_t begin = 0;
1948
  off_t pos = 0;
1949
 
1950
  HBAptr = NULL;
1951
  for (i = 0; i < 2; i++)
1952
  {
1953
    if ((HBAptr = atp_host[i]) != NULL)
1954
    {
1955
      if (HBAptr->host_no == hostno)
1956
      {
1957
        break;
1958
      }
1959
      HBAptr = NULL;
1960
    }
1961
  }
1962
 
1963
  if (HBAptr == NULL)
1964
  {
1965
    size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
1966
    len += size; pos = begin + len; size = 0;
1967
    goto stop_output;
1968
  }
1969
 
1970
  if (inout == TRUE) /* Has data been written to the file? */
1971
  {
1972
    return (atp870u_set_info(buffer, length, HBAptr));
1973
  }
1974
 
1975
  if (offset == 0)
1976
  {
1977
    memset(buff, 0, sizeof(buff));
1978
  }
1979
 
1980
  size += sprintf(BLS, "ACARD AEC-671X Driver Version: 1.0\n");
1981
  len += size; pos = begin + len; size = 0;
1982
 
1983
  size += sprintf(BLS, "\n");
1984
  size += sprintf(BLS, "Adapter Configuration:\n");
1985
  size += sprintf(BLS, "               Base IO: %#.4x\n", HBAptr->io_port);
1986
  size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
1987
  len += size; pos = begin + len; size = 0;
1988
 
1989
stop_output:
1990
  *start = buffer + (offset - begin);   /* Start of wanted data */
1991
  len -= (offset - begin);      /* Start slop */
1992
  if (len > length)
1993
  {
1994
    len = length;               /* Ending slop */
1995
  }
1996
 
1997
  return (len);
1998
}
1999
 
2000
#include "sd.h"
2001
 
2002
int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
2003
{
2004
  int heads, sectors, cylinders;
2005
 
2006
  heads = 64;
2007
  sectors = 32;
2008
  cylinders = disk->capacity / (heads * sectors);
2009
 
2010
  if ( cylinders > 1024 )
2011
  {
2012
    heads = 255;
2013
    sectors = 63;
2014
    cylinders = disk->capacity / (heads * sectors);
2015
  }
2016
 
2017
  ip[0] = heads;
2018
  ip[1] = sectors;
2019
  ip[2] = cylinders;
2020
 
2021
  return 0;
2022
}
2023
 
2024
#ifdef MODULE
2025
Scsi_Host_Template driver_template = ATP870U;
2026
 
2027
#include "scsi_module.c"
2028
#endif
2029
 

powered by: WebSVN 2.1.0

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