Merge HEAD from ../scsi-misc-2.6-tmp
[sfrench/cifs-2.6.git] / drivers / scsi / atp870u.c
1 /* 
2  *  Copyright (C) 1997  Wu Ching Chen
3  *  2.1.x update (C) 1998  Krzysztof G. Baranowski
4  *  2.5.x update (C) 2002  Red Hat <alan@redhat.com>
5  *  2.6.x update (C) 2004  Red Hat <alan@redhat.com>
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  * atp885 support add by ACARD Hao Ping Lian 2005/01/05
18  */
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/interrupt.h>
22 #include <linux/kernel.h>
23 #include <linux/types.h>
24 #include <linux/string.h>
25 #include <linux/ioport.h>
26 #include <linux/delay.h>
27 #include <linux/proc_fs.h>
28 #include <linux/spinlock.h>
29 #include <linux/pci.h>
30 #include <linux/blkdev.h>
31 #include <asm/system.h>
32 #include <asm/io.h>
33
34 #include <scsi/scsi.h>
35 #include <scsi/scsi_cmnd.h>
36 #include <scsi/scsi_device.h>
37 #include <scsi/scsi_host.h>
38
39 #include "atp870u.h"
40
41 static struct scsi_host_template atp870u_template;
42 static void send_s870(struct atp_unit *dev,unsigned char c);
43 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c);
44 static void tscam_885(void);
45
46 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
47 {
48         unsigned long flags;
49         unsigned short int tmpcip, id;
50         unsigned char i, j, c, target_id, lun,cmdp;
51         unsigned char *prd;
52         struct scsi_cmnd *workreq;
53         unsigned int workport, tmport, tmport1;
54         unsigned long adrcnt, k;
55 #ifdef ED_DBGP
56         unsigned long l;
57 #endif
58         int errstus;
59         struct Scsi_Host *host = dev_id;
60         struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
61
62         for (c = 0; c < 2; c++) {
63                 tmport = dev->ioport[c] + 0x1f;
64                 j = inb(tmport);
65                 if ((j & 0x80) != 0)
66                 {                       
67                         goto ch_sel;
68                 }
69                 dev->in_int[c] = 0;
70         }
71         return IRQ_NONE;
72 ch_sel:
73 #ifdef ED_DBGP  
74         printk("atp870u_intr_handle enter\n");
75 #endif  
76         dev->in_int[c] = 1;
77         cmdp = inb(dev->ioport[c] + 0x10);
78         workport = dev->ioport[c];
79         if (dev->working[c] != 0) {
80                 if (dev->dev_id == ATP885_DEVID) {
81                         tmport1 = workport + 0x16;
82                         if ((inb(tmport1) & 0x80) == 0)
83                                 outb((inb(tmport1) | 0x80), tmport1);
84                 }               
85                 tmpcip = dev->pciport[c];
86                 if ((inb(tmpcip) & 0x08) != 0)
87                 {
88                         tmpcip += 0x2;
89                         for (k=0; k < 1000; k++) {
90                                 if ((inb(tmpcip) & 0x08) == 0) {
91                                         goto stop_dma;
92                                 }
93                                 if ((inb(tmpcip) & 0x01) == 0) {
94                                         goto stop_dma;
95                                 }
96                         }
97                 }
98 stop_dma:
99                 tmpcip = dev->pciport[c];
100                 outb(0x00, tmpcip);
101                 tmport -= 0x08;
102                 
103                 i = inb(tmport);
104                 
105                 if (dev->dev_id == ATP885_DEVID) {
106                         tmpcip += 2;
107                         outb(0x06, tmpcip);
108                         tmpcip -= 2;
109                 }
110
111                 tmport -= 0x02;
112                 target_id = inb(tmport);
113                 tmport += 0x02;
114
115                 /*
116                  *      Remap wide devices onto id numbers
117                  */
118
119                 if ((target_id & 0x40) != 0) {
120                         target_id = (target_id & 0x07) | 0x08;
121                 } else {
122                         target_id &= 0x07;
123                 }
124
125                 if ((j & 0x40) != 0) {
126                      if (dev->last_cmd[c] == 0xff) {
127                         dev->last_cmd[c] = target_id;
128                      }
129                      dev->last_cmd[c] |= 0x40;
130                 }
131                 if (dev->dev_id == ATP885_DEVID) 
132                         dev->r1f[c][target_id] |= j;
133 #ifdef ED_DBGP
134                 printk("atp870u_intr_handle status = %x\n",i);
135 #endif  
136                 if (i == 0x85) {
137                         if ((dev->last_cmd[c] & 0xf0) != 0x40) {
138                            dev->last_cmd[c] = 0xff;
139                         }
140                         if (dev->dev_id == ATP885_DEVID) {
141                                 tmport -= 0x05;
142                                 adrcnt = 0;
143                                 ((unsigned char *) &adrcnt)[2] = inb(tmport++);
144                                 ((unsigned char *) &adrcnt)[1] = inb(tmport++);
145                                 ((unsigned char *) &adrcnt)[0] = inb(tmport);
146                                 if (dev->id[c][target_id].last_len != adrcnt)
147                                 {
148                                         k = dev->id[c][target_id].last_len;
149                                         k -= adrcnt;
150                                         dev->id[c][target_id].tran_len = k;                        
151                                 dev->id[c][target_id].last_len = adrcnt;                           
152                                 }
153 #ifdef ED_DBGP
154                                 printk("tmport = %x dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",tmport,dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len);
155 #endif          
156                         }
157
158                         /*
159                          *      Flip wide
160                          */                     
161                         if (dev->wide_id[c] != 0) {
162                                 tmport = workport + 0x1b;
163                                 outb(0x01, tmport);
164                                 while ((inb(tmport) & 0x01) != 0x01) {
165                                         outb(0x01, tmport);
166                                 }
167                         }               
168                         /*
169                          *      Issue more commands
170                          */
171                         spin_lock_irqsave(dev->host->host_lock, flags);                                          
172                         if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) &&
173                             (dev->in_snd[c] == 0)) {
174 #ifdef ED_DBGP
175                                 printk("Call sent_s870\n");
176 #endif                          
177                                 send_s870(dev,c);
178                         }
179                         spin_unlock_irqrestore(dev->host->host_lock, flags);
180                         /*
181                          *      Done
182                          */
183                         dev->in_int[c] = 0;
184 #ifdef ED_DBGP
185                                 printk("Status 0x85 return\n");
186 #endif                          
187                         goto handled;
188                 }
189
190                 if (i == 0x40) {
191                      dev->last_cmd[c] |= 0x40;
192                      dev->in_int[c] = 0;
193                      goto handled;
194                 }
195
196                 if (i == 0x21) {
197                         if ((dev->last_cmd[c] & 0xf0) != 0x40) {
198                            dev->last_cmd[c] = 0xff;
199                         }
200                         tmport -= 0x05;
201                         adrcnt = 0;
202                         ((unsigned char *) &adrcnt)[2] = inb(tmport++);
203                         ((unsigned char *) &adrcnt)[1] = inb(tmport++);
204                         ((unsigned char *) &adrcnt)[0] = inb(tmport);
205                         k = dev->id[c][target_id].last_len;
206                         k -= adrcnt;
207                         dev->id[c][target_id].tran_len = k;
208                         dev->id[c][target_id].last_len = adrcnt;
209                         tmport -= 0x04;
210                         outb(0x41, tmport);
211                         tmport += 0x08;
212                         outb(0x08, tmport);
213                         dev->in_int[c] = 0;
214                         goto handled;
215                 }
216
217                 if (dev->dev_id == ATP885_DEVID) {
218                         if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) {
219                                 if ((i == 0x4c) || (i == 0x8c)) 
220                                         i=0x48;
221                                 else 
222                                         i=0x49;
223                         }       
224                         
225                 }
226                 if ((i == 0x80) || (i == 0x8f)) {
227 #ifdef ED_DBGP
228                         printk(KERN_DEBUG "Device reselect\n");
229 #endif                  
230                         lun = 0;
231                         tmport -= 0x07;
232                         if (cmdp == 0x44 || i==0x80) {
233                                 tmport += 0x0d;
234                                 lun = inb(tmport) & 0x07;
235                         } else {
236                                 if ((dev->last_cmd[c] & 0xf0) != 0x40) {
237                                    dev->last_cmd[c] = 0xff;
238                                 }
239                                 if (cmdp == 0x41) {
240 #ifdef ED_DBGP
241                                         printk("cmdp = 0x41\n");
242 #endif                                          
243                                         tmport += 0x02;
244                                         adrcnt = 0;
245                                         ((unsigned char *) &adrcnt)[2] = inb(tmport++);
246                                         ((unsigned char *) &adrcnt)[1] = inb(tmport++);
247                                         ((unsigned char *) &adrcnt)[0] = inb(tmport);
248                                         k = dev->id[c][target_id].last_len;
249                                         k -= adrcnt;
250                                         dev->id[c][target_id].tran_len = k;
251                                         dev->id[c][target_id].last_len = adrcnt;
252                                         tmport += 0x04;
253                                         outb(0x08, tmport);
254                                         dev->in_int[c] = 0;
255                                         goto handled;
256                                 } else {
257 #ifdef ED_DBGP
258                                         printk("cmdp != 0x41\n");
259 #endif                                          
260                                         outb(0x46, tmport);
261                                         dev->id[c][target_id].dirct = 0x00;
262                                         tmport += 0x02;
263                                         outb(0x00, tmport++);
264                                         outb(0x00, tmport++);
265                                         outb(0x00, tmport++);
266                                         tmport += 0x03;
267                                         outb(0x08, tmport);
268                                         dev->in_int[c] = 0;
269                                         goto handled;
270                                 }
271                         }
272                         if (dev->last_cmd[c] != 0xff) {
273                            dev->last_cmd[c] |= 0x40;
274                         }
275                         if (dev->dev_id == ATP885_DEVID) {
276                                 j = inb(dev->baseport + 0x29) & 0xfe;
277                                 outb(j, dev->baseport + 0x29);
278                                 tmport = workport + 0x16;
279                         } else {
280                                 tmport = workport + 0x10;
281                                 outb(0x45, tmport);
282                                 tmport += 0x06;                         
283                         }
284                         
285                         target_id = inb(tmport);
286                         /*
287                          *      Remap wide identifiers
288                          */
289                         if ((target_id & 0x10) != 0) {
290                                 target_id = (target_id & 0x07) | 0x08;
291                         } else {
292                                 target_id &= 0x07;
293                         }
294                         if (dev->dev_id == ATP885_DEVID) {
295                                 tmport = workport + 0x10;
296                                 outb(0x45, tmport);
297                         }
298                         workreq = dev->id[c][target_id].curr_req;
299 #ifdef ED_DBGP                  
300                         printk(KERN_DEBUG "Channel = %d ID = %d LUN = %d CDB",c,workreq->device->id,workreq->device->lun);
301                         for(l=0;l<workreq->cmd_len;l++)
302                         {
303                                 printk(KERN_DEBUG " %x",workreq->cmnd[l]);
304                         }
305 #endif  
306                         
307                         tmport = workport + 0x0f;
308                         outb(lun, tmport);
309                         tmport += 0x02;
310                         outb(dev->id[c][target_id].devsp, tmport++);
311                         adrcnt = dev->id[c][target_id].tran_len;
312                         k = dev->id[c][target_id].last_len;
313
314                         outb(((unsigned char *) &k)[2], tmport++);
315                         outb(((unsigned char *) &k)[1], tmport++);
316                         outb(((unsigned char *) &k)[0], tmport++);
317 #ifdef ED_DBGP                  
318                         printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(tmport-1), inb(tmport-2), inb(tmport-3));
319 #endif                  
320                         /* Remap wide */
321                         j = target_id;
322                         if (target_id > 7) {
323                                 j = (j & 0x07) | 0x40;
324                         }
325                         /* Add direction */
326                         j |= dev->id[c][target_id].dirct;
327                         outb(j, tmport++);
328                         outb(0x80,tmport);
329                         
330                         /* enable 32 bit fifo transfer */       
331                         if (dev->dev_id == ATP885_DEVID) {
332                                 tmpcip = dev->pciport[c] + 1;
333                                 i=inb(tmpcip) & 0xf3;
334                                 //j=workreq->cmnd[0];                           
335                                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
336                                    i |= 0x0c;
337                                 }
338                                 outb(i,tmpcip);                                         
339                         } else if ((dev->dev_id == ATP880_DEVID1) ||
340                                    (dev->dev_id == ATP880_DEVID2) ) {
341                                 tmport = workport - 0x05;
342                                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
343                                         outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
344                                 } else {
345                                         outb((unsigned char) (inb(tmport) & 0x3f), tmport);
346                                 }
347                         } else {                                
348                                 tmport = workport + 0x3a;
349                                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
350                                         outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport);
351                                 } else {
352                                         outb((unsigned char) (inb(tmport) & 0xf3), tmport);
353                                 }                                                                                                               
354                         }       
355                         tmport = workport + 0x1b;
356                         j = 0;
357                         id = 1;
358                         id = id << target_id;
359                         /*
360                          *      Is this a wide device
361                          */
362                         if ((id & dev->wide_id[c]) != 0) {
363                                 j |= 0x01;
364                         }
365                         outb(j, tmport);
366                         while ((inb(tmport) & 0x01) != j) {
367                                 outb(j,tmport);
368                         }
369                         if (dev->id[c][target_id].last_len == 0) {
370                                 tmport = workport + 0x18;
371                                 outb(0x08, tmport);
372                                 dev->in_int[c] = 0;
373 #ifdef ED_DBGP
374                                 printk("dev->id[c][target_id].last_len = 0\n");
375 #endif                                  
376                                 goto handled;
377                         }
378 #ifdef ED_DBGP
379                         printk("target_id = %d adrcnt = %d\n",target_id,adrcnt);
380 #endif                  
381                         prd = dev->id[c][target_id].prd_pos;
382                         while (adrcnt != 0) {
383                                 id = ((unsigned short int *)prd)[2];
384                                 if (id == 0) {
385                                         k = 0x10000;
386                                 } else {
387                                         k = id;
388                                 }
389                                 if (k > adrcnt) {
390                                         ((unsigned short int *)prd)[2] = (unsigned short int)
391                                             (k - adrcnt);
392                                         ((unsigned long *)prd)[0] += adrcnt;
393                                         adrcnt = 0;
394                                         dev->id[c][target_id].prd_pos = prd;
395                                 } else {
396                                         adrcnt -= k;
397                                         dev->id[c][target_id].prdaddr += 0x08;
398                                         prd += 0x08;
399                                         if (adrcnt == 0) {
400                                                 dev->id[c][target_id].prd_pos = prd;
401                                         }
402                                 }                               
403                         }
404                         tmpcip = dev->pciport[c] + 0x04;
405                         outl(dev->id[c][target_id].prdaddr, tmpcip);
406 #ifdef ED_DBGP
407                         printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr);
408 #endif
409                         if (dev->dev_id == ATP885_DEVID) {
410                                 tmpcip -= 0x04;
411                         } else {
412                                 tmpcip -= 0x02;
413                                 outb(0x06, tmpcip);
414                                 outb(0x00, tmpcip);
415                                 tmpcip -= 0x02;
416                         }
417                         tmport = workport + 0x18;
418                         /*
419                          *      Check transfer direction
420                          */
421                         if (dev->id[c][target_id].dirct != 0) {
422                                 outb(0x08, tmport);
423                                 outb(0x01, tmpcip);
424                                 dev->in_int[c] = 0;
425 #ifdef ED_DBGP
426                                 printk("status 0x80 return dirct != 0\n");
427 #endif                          
428                                 goto handled;
429                         }
430                         outb(0x08, tmport);
431                         outb(0x09, tmpcip);
432                         dev->in_int[c] = 0;
433 #ifdef ED_DBGP
434                         printk("status 0x80 return dirct = 0\n");
435 #endif                  
436                         goto handled;
437                 }
438
439                 /*
440                  *      Current scsi request on this target
441                  */
442
443                 workreq = dev->id[c][target_id].curr_req;
444
445                 if (i == 0x42) {
446                         if ((dev->last_cmd[c] & 0xf0) != 0x40)
447                         {
448                            dev->last_cmd[c] = 0xff;
449                         }
450                         errstus = 0x02;
451                         workreq->result = errstus;
452                         goto go_42;
453                 }
454                 if (i == 0x16) {
455                         if ((dev->last_cmd[c] & 0xf0) != 0x40) {
456                            dev->last_cmd[c] = 0xff;
457                         }
458                         errstus = 0;
459                         tmport -= 0x08;
460                         errstus = inb(tmport);
461                         if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) {
462                            printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
463                            errstus = 0x02;
464                         }
465                         workreq->result = errstus;
466 go_42:
467                         if (dev->dev_id == ATP885_DEVID) {              
468                                 j = inb(dev->baseport + 0x29) | 0x01;
469                                 outb(j, dev->baseport + 0x29);
470                         }
471                         /*
472                          *      Complete the command
473                          */
474                         if (workreq->use_sg) {
475                                 pci_unmap_sg(dev->pdev,
476                                         (struct scatterlist *)workreq->buffer,
477                                         workreq->use_sg,
478                                         workreq->sc_data_direction);
479                         } else if (workreq->request_bufflen &&
480                                         workreq->sc_data_direction != DMA_NONE) {
481                                 pci_unmap_single(dev->pdev,
482                                         workreq->SCp.dma_handle,
483                                         workreq->request_bufflen,
484                                         workreq->sc_data_direction);
485                         }                       
486                         spin_lock_irqsave(dev->host->host_lock, flags);
487                         (*workreq->scsi_done) (workreq);
488 #ifdef ED_DBGP
489                            printk("workreq->scsi_done\n");
490 #endif  
491                         /*
492                          *      Clear it off the queue
493                          */
494                         dev->id[c][target_id].curr_req = NULL;
495                         dev->working[c]--;
496                         spin_unlock_irqrestore(dev->host->host_lock, flags);
497                         /*
498                          *      Take it back wide
499                          */
500                         if (dev->wide_id[c] != 0) {
501                                 tmport = workport + 0x1b;
502                                 outb(0x01, tmport);
503                                 while ((inb(tmport) & 0x01) != 0x01) {
504                                         outb(0x01, tmport);
505                                 }       
506                         } 
507                         /*
508                          *      If there is stuff to send and nothing going then send it
509                          */
510                         spin_lock_irqsave(dev->host->host_lock, flags);
511                         if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) &&
512                             (dev->in_snd[c] == 0)) {
513 #ifdef ED_DBGP
514                            printk("Call sent_s870(scsi_done)\n");
515 #endif                             
516                            send_s870(dev,c);
517                         }
518                         spin_unlock_irqrestore(dev->host->host_lock, flags);
519                         dev->in_int[c] = 0;
520                         goto handled;
521                 }
522                 if ((dev->last_cmd[c] & 0xf0) != 0x40) {
523                    dev->last_cmd[c] = 0xff;
524                 }
525                 if (i == 0x4f) {
526                         i = 0x89;
527                 }
528                 i &= 0x0f;
529                 if (i == 0x09) {
530                         tmpcip += 4;
531                         outl(dev->id[c][target_id].prdaddr, tmpcip);
532                         tmpcip = tmpcip - 2;
533                         outb(0x06, tmpcip);
534                         outb(0x00, tmpcip);
535                         tmpcip = tmpcip - 2;
536                         tmport = workport + 0x10;
537                         outb(0x41, tmport);
538                         if (dev->dev_id == ATP885_DEVID) {
539                                 tmport += 2;
540                                 k = dev->id[c][target_id].last_len;
541                                 outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++);
542                                 outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++);
543                                 outb((unsigned char) (((unsigned char *) (&k))[0]), tmport);
544                                 dev->id[c][target_id].dirct = 0x00;
545                                 tmport += 0x04;
546                         } else {
547                                 dev->id[c][target_id].dirct = 0x00;
548                                 tmport += 0x08;                         
549                         }
550                         outb(0x08, tmport);
551                         outb(0x09, tmpcip);
552                         dev->in_int[c] = 0;
553                         goto handled;
554                 }
555                 if (i == 0x08) {
556                         tmpcip += 4;
557                         outl(dev->id[c][target_id].prdaddr, tmpcip);
558                         tmpcip = tmpcip - 2;
559                         outb(0x06, tmpcip);
560                         outb(0x00, tmpcip);
561                         tmpcip = tmpcip - 2;
562                         tmport = workport + 0x10;
563                         outb(0x41, tmport);
564                         if (dev->dev_id == ATP885_DEVID) {              
565                                 tmport += 2;
566                                 k = dev->id[c][target_id].last_len;
567                                 outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++);
568                                 outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++);
569                                 outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++);
570                         } else {
571                                 tmport += 5;
572                         }
573                         outb((unsigned char) (inb(tmport) | 0x20), tmport);
574                         dev->id[c][target_id].dirct = 0x20;
575                         tmport += 0x03;
576                         outb(0x08, tmport);
577                         outb(0x01, tmpcip);
578                         dev->in_int[c] = 0;
579                         goto handled;
580                 }
581                 tmport -= 0x07;
582                 if (i == 0x0a) {
583                         outb(0x30, tmport);
584                 } else {
585                         outb(0x46, tmport);
586                 }
587                 dev->id[c][target_id].dirct = 0x00;
588                 tmport += 0x02;
589                 outb(0x00, tmport++);
590                 outb(0x00, tmport++);
591                 outb(0x00, tmport++);
592                 tmport += 0x03;
593                 outb(0x08, tmport);
594                 dev->in_int[c] = 0;
595                 goto handled;
596         } else {
597 //              tmport = workport + 0x17;
598 //              inb(tmport);
599 //              dev->working[c] = 0;
600                 dev->in_int[c] = 0;
601                 goto handled;
602         }
603         
604 handled:
605 #ifdef ED_DBGP
606         printk("atp870u_intr_handle exit\n");
607 #endif                  
608         return IRQ_HANDLED;
609 }
610 /**
611  *      atp870u_queuecommand    -       Queue SCSI command
612  *      @req_p: request block
613  *      @done: completion function
614  *
615  *      Queue a command to the ATP queue. Called with the host lock held.
616  */
617 static int atp870u_queuecommand(struct scsi_cmnd * req_p, 
618                          void (*done) (struct scsi_cmnd *))
619 {
620         unsigned char c;
621         unsigned int tmport,m;  
622         struct atp_unit *dev;
623         struct Scsi_Host *host;
624
625         c = req_p->device->channel;     
626         req_p->sense_buffer[0]=0;
627         req_p->resid = 0;
628         if (req_p->device->channel > 1) {
629                 req_p->result = 0x00040000;
630                 done(req_p);
631 #ifdef ED_DBGP          
632                 printk("atp870u_queuecommand : req_p->device->channel > 1\n");  
633 #endif                  
634                 return 0;
635         }
636
637         host = req_p->device->host;
638         dev = (struct atp_unit *)&host->hostdata;
639                 
640
641                 
642         m = 1;
643         m = m << req_p->device->id;
644
645         /*
646          *      Fake a timeout for missing targets
647          */
648
649         if ((m & dev->active_id[c]) == 0) {
650                 req_p->result = 0x00040000;
651                 done(req_p);
652                 return 0;
653         }
654
655         if (done) {
656                 req_p->scsi_done = done;
657         } else {
658 #ifdef ED_DBGP          
659                 printk( "atp870u_queuecommand: done can't be NULL\n");
660 #endif          
661                 req_p->result = 0;
662                 done(req_p);
663                 return 0;
664         }
665         
666         /*
667          *      Count new command
668          */
669         dev->quend[c]++;
670         if (dev->quend[c] >= qcnt) {
671                 dev->quend[c] = 0;
672         }
673         
674         /*
675          *      Check queue state
676          */
677         if (dev->quhd[c] == dev->quend[c]) {
678                 if (dev->quend[c] == 0) {
679                         dev->quend[c] = qcnt;
680                 }
681 #ifdef ED_DBGP          
682                 printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n");
683 #endif          
684                 dev->quend[c]--;
685                 req_p->result = 0x00020000;
686                 done(req_p);    
687                 return 0;
688         }
689         dev->quereq[c][dev->quend[c]] = req_p;
690         tmport = dev->ioport[c] + 0x1c;
691 #ifdef ED_DBGP  
692         printk("dev->ioport[c] = %x inb(tmport) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(tmport),c,dev->in_int[c],c,dev->in_snd[c]);
693 #endif
694         if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) {
695 #ifdef ED_DBGP
696                 printk("Call sent_s870(atp870u_queuecommand)\n");
697 #endif          
698                 send_s870(dev,c);
699         }
700 #ifdef ED_DBGP  
701         printk("atp870u_queuecommand : exit\n");
702 #endif  
703         return 0;
704 }
705
706 /**
707  *      send_s870       -       send a command to the controller
708  *      @host: host
709  *
710  *      On entry there is work queued to be done. We move some of that work to the
711  *      controller itself. 
712  *
713  *      Caller holds the host lock.
714  */
715 static void send_s870(struct atp_unit *dev,unsigned char c)
716 {
717         unsigned int tmport;
718         struct scsi_cmnd *workreq;
719         unsigned int i;//,k;
720         unsigned char  j, target_id;
721         unsigned char *prd;
722         unsigned short int tmpcip, w;
723         unsigned long l, bttl = 0;
724         unsigned int workport;
725         struct scatterlist *sgpnt;
726         unsigned long  sg_count;
727
728         if (dev->in_snd[c] != 0) {
729 #ifdef ED_DBGP          
730                 printk("cmnd in_snd\n");
731 #endif
732                 return;
733         }
734 #ifdef ED_DBGP
735         printk("Sent_s870 enter\n");
736 #endif
737         dev->in_snd[c] = 1;
738         if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) {
739                 dev->last_cmd[c] &= 0x0f;
740                 workreq = dev->id[c][dev->last_cmd[c]].curr_req;
741                 if (workreq != NULL) {  /* check NULL pointer */
742                    goto cmd_subp;
743                 }
744                 dev->last_cmd[c] = 0xff;        
745                 if (dev->quhd[c] == dev->quend[c]) {
746                         dev->in_snd[c] = 0;
747                         return ;
748                 }
749         }
750         if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) {
751                 dev->in_snd[c] = 0;
752                 return ;
753         }
754         dev->working[c]++;
755         j = dev->quhd[c];
756         dev->quhd[c]++;
757         if (dev->quhd[c] >= qcnt) {
758                 dev->quhd[c] = 0;
759         }
760         workreq = dev->quereq[c][dev->quhd[c]];
761         if (dev->id[c][workreq->device->id].curr_req == 0) {    
762                 dev->id[c][workreq->device->id].curr_req = workreq;
763                 dev->last_cmd[c] = workreq->device->id;
764                 goto cmd_subp;
765         }       
766         dev->quhd[c] = j;
767         dev->working[c]--;
768         dev->in_snd[c] = 0;
769         return;
770 cmd_subp:
771         workport = dev->ioport[c];
772         tmport = workport + 0x1f;
773         if ((inb(tmport) & 0xb0) != 0) {
774                 goto abortsnd;
775         }
776         tmport = workport + 0x1c;
777         if (inb(tmport) == 0) {
778                 goto oktosend;
779         }
780 abortsnd:
781 #ifdef ED_DBGP
782         printk("Abort to Send\n");
783 #endif
784         dev->last_cmd[c] |= 0x40;
785         dev->in_snd[c] = 0;
786         return;
787 oktosend:
788 #ifdef ED_DBGP
789         printk("OK to Send\n");
790         printk("CDB");
791         for(i=0;i<workreq->cmd_len;i++) {
792                 printk(" %x",workreq->cmnd[i]);
793         }
794         printk("\nChannel = %d ID = %d LUN = %d\n",c,workreq->device->id,workreq->device->lun);
795 #endif  
796         if (dev->dev_id == ATP885_DEVID) {
797                 j = inb(dev->baseport + 0x29) & 0xfe;
798                 outb(j, dev->baseport + 0x29);
799                 dev->r1f[c][workreq->device->id] = 0;
800         }
801         
802         if (workreq->cmnd[0] == READ_CAPACITY) {
803                 if (workreq->request_bufflen > 8) {
804                         workreq->request_bufflen = 0x08;
805                 }
806         }
807         if (workreq->cmnd[0] == 0x00) {
808                 workreq->request_bufflen = 0;
809         }
810
811         tmport = workport + 0x1b;
812         j = 0;
813         target_id = workreq->device->id;
814
815         /*
816          *      Wide ?
817          */
818         w = 1;
819         w = w << target_id;
820         if ((w & dev->wide_id[c]) != 0) {
821                 j |= 0x01;
822         }
823         outb(j, tmport);
824         while ((inb(tmport) & 0x01) != j) {
825                 outb(j,tmport);
826 #ifdef ED_DBGP
827                 printk("send_s870 while loop 1\n");
828 #endif
829         }
830         /*
831          *      Write the command
832          */
833
834         tmport = workport;
835         outb(workreq->cmd_len, tmport++);
836         outb(0x2c, tmport++);
837         if (dev->dev_id == ATP885_DEVID) {
838                 outb(0x7f, tmport++);
839         } else {
840                 outb(0xcf, tmport++);   
841         }       
842         for (i = 0; i < workreq->cmd_len; i++) {
843                 outb(workreq->cmnd[i], tmport++);
844         }
845         tmport = workport + 0x0f;
846         outb(workreq->device->lun, tmport);
847         tmport += 0x02;
848         /*
849          *      Write the target
850          */
851         outb(dev->id[c][target_id].devsp, tmport++);     
852 #ifdef ED_DBGP  
853         printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp);
854 #endif
855         /*
856          *      Figure out the transfer size
857          */
858         if (workreq->use_sg) {
859 #ifdef ED_DBGP
860                 printk("Using SGL\n");
861 #endif          
862                 l = 0;
863                 
864                 sgpnt = (struct scatterlist *) workreq->request_buffer;
865                 sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg,
866                                 workreq->sc_data_direction);            
867                 
868                 for (i = 0; i < workreq->use_sg; i++) {
869                         if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) {
870                                 panic("Foooooooood fight!");
871                         }
872                         l += sgpnt[i].length;
873                 }
874 #ifdef ED_DBGP          
875                 printk( "send_s870: workreq->use_sg %d, sg_count %d l %8ld\n", workreq->use_sg, sg_count, l);
876 #endif
877         } else if(workreq->request_bufflen && workreq->sc_data_direction != PCI_DMA_NONE) {
878 #ifdef ED_DBGP
879                 printk("Not using SGL\n");
880 #endif                                  
881                 workreq->SCp.dma_handle = pci_map_single(dev->pdev, workreq->request_buffer,
882                                 workreq->request_bufflen,
883                                 workreq->sc_data_direction);            
884                 l = workreq->request_bufflen;
885 #ifdef ED_DBGP          
886                 printk( "send_s870: workreq->use_sg %d, l %8ld\n", workreq->use_sg, l);
887 #endif
888         } else l = 0;
889         /*
890          *      Write transfer size
891          */
892         outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
893         outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
894         outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
895         j = target_id;  
896         dev->id[c][j].last_len = l;
897         dev->id[c][j].tran_len = 0;
898 #ifdef ED_DBGP  
899         printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len);
900 #endif  
901         /*
902          *      Flip the wide bits
903          */
904         if ((j & 0x08) != 0) {
905                 j = (j & 0x07) | 0x40;
906         }
907         /*
908          *      Check transfer direction
909          */
910         if (workreq->sc_data_direction == DMA_TO_DEVICE) {
911                 outb((unsigned char) (j | 0x20), tmport++);
912         } else {
913                 outb(j, tmport++);
914         }
915         outb((unsigned char) (inb(tmport) | 0x80), tmport);
916         outb(0x80, tmport);
917         tmport = workport + 0x1c;
918         dev->id[c][target_id].dirct = 0;
919         if (l == 0) {
920                 if (inb(tmport) == 0) {
921                         tmport = workport + 0x18;
922 #ifdef ED_DBGP
923                         printk("change SCSI_CMD_REG 0x08\n");   
924 #endif                          
925                         outb(0x08, tmport);
926                 } else {
927                         dev->last_cmd[c] |= 0x40;
928                 }
929                 dev->in_snd[c] = 0;
930                 return;
931         }
932         tmpcip = dev->pciport[c];
933         prd = dev->id[c][target_id].prd_table;
934         dev->id[c][target_id].prd_pos = prd;
935
936         /*
937          *      Now write the request list. Either as scatter/gather or as
938          *      a linear chain.
939          */
940
941         if (workreq->use_sg) {
942                 sgpnt = (struct scatterlist *) workreq->request_buffer;
943                 i = 0;
944                 for (j = 0; j < workreq->use_sg; j++) {
945                         bttl = sg_dma_address(&sgpnt[j]);
946                         l=sg_dma_len(&sgpnt[j]);
947 #ifdef ED_DBGP          
948                 printk("1. bttl %x, l %x\n",bttl, l);
949 #endif                  
950                 while (l > 0x10000) {
951                                 (((u16 *) (prd))[i + 3]) = 0x0000;
952                                 (((u16 *) (prd))[i + 2]) = 0x0000;
953                                 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
954                                 l -= 0x10000;
955                                 bttl += 0x10000;
956                                 i += 0x04;
957                         }
958                         (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
959                         (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
960                         (((u16 *) (prd))[i + 3]) = 0;
961                         i += 0x04;                      
962                 }
963                 (((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000); 
964 #ifdef ED_DBGP          
965                 printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3]));
966                 printk("2. bttl %x, l %x\n",bttl, l);
967 #endif                  
968         } else {
969                 /*
970                  *      For a linear request write a chain of blocks
971                  */        
972                 bttl = workreq->SCp.dma_handle;
973                 l = workreq->request_bufflen;
974                 i = 0;
975 #ifdef ED_DBGP          
976                 printk("3. bttl %x, l %x\n",bttl, l);
977 #endif                  
978                 while (l > 0x10000) {
979                                 (((u16 *) (prd))[i + 3]) = 0x0000;
980                                 (((u16 *) (prd))[i + 2]) = 0x0000;
981                                 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);
982                                 l -= 0x10000;
983                                 bttl += 0x10000;
984                                 i += 0x04;
985                         }
986                         (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000);
987                         (((u16 *) (prd))[i + 2]) = cpu_to_le16(l);
988                         (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl);          
989 #ifdef ED_DBGP          
990                 printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3]));
991                 printk("4. bttl %x, l %x\n",bttl, l);
992 #endif                  
993                 
994         }
995         tmpcip += 4;
996 #ifdef ED_DBGP          
997         printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
998 #endif  
999         outl(dev->id[c][target_id].prdaddr, tmpcip);
1000         tmpcip = tmpcip - 2;
1001         outb(0x06, tmpcip);
1002         outb(0x00, tmpcip);
1003         if (dev->dev_id == ATP885_DEVID) {
1004                 tmpcip--;
1005                 j=inb(tmpcip) & 0xf3;
1006                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) ||
1007                 (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
1008                         j |= 0x0c;
1009                 }
1010                 outb(j,tmpcip);
1011                 tmpcip--;               
1012         } else if ((dev->dev_id == ATP880_DEVID1) ||
1013                    (dev->dev_id == ATP880_DEVID2)) {
1014                 tmpcip =tmpcip -2;      
1015                 tmport = workport - 0x05;
1016                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
1017                         outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport);
1018                 } else {
1019                         outb((unsigned char) (inb(tmport) & 0x3f), tmport);
1020                 }               
1021         } else {                
1022                 tmpcip =tmpcip -2;
1023                 tmport = workport + 0x3a;
1024                 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
1025                         outb((inb(tmport) & 0xf3) | 0x08, tmport);
1026                 } else {
1027                         outb(inb(tmport) & 0xf3, tmport);
1028                 }               
1029         }       
1030         tmport = workport + 0x1c;
1031
1032         if(workreq->sc_data_direction == DMA_TO_DEVICE) {
1033                 dev->id[c][target_id].dirct = 0x20;
1034                 if (inb(tmport) == 0) {
1035                         tmport = workport + 0x18;
1036                         outb(0x08, tmport);
1037                         outb(0x01, tmpcip);
1038 #ifdef ED_DBGP          
1039                 printk( "start DMA(to target)\n");
1040 #endif                          
1041                 } else {
1042                         dev->last_cmd[c] |= 0x40;
1043                 }
1044                 dev->in_snd[c] = 0;
1045                 return;
1046         }
1047         if (inb(tmport) == 0) {         
1048                 tmport = workport + 0x18;
1049                 outb(0x08, tmport);
1050                 outb(0x09, tmpcip);
1051 #ifdef ED_DBGP          
1052                 printk( "start DMA(to host)\n");
1053 #endif                  
1054         } else {
1055                 dev->last_cmd[c] |= 0x40;
1056         }
1057         dev->in_snd[c] = 0;
1058         return;
1059
1060 }
1061
1062 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
1063 {
1064         unsigned int tmport;
1065         unsigned short int i, k;
1066         unsigned char j;
1067
1068         tmport = dev->ioport[0] + 0x1c;
1069         outw(*val, tmport);
1070 FUN_D7:
1071         for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns)  */
1072                 k = inw(tmport);
1073                 j = (unsigned char) (k >> 8);
1074                 if ((k & 0x8000) != 0) {        /* DB7 all release?    */
1075                         goto FUN_D7;
1076                 }
1077         }
1078         *val |= 0x4000;         /* assert DB6           */
1079         outw(*val, tmport);
1080         *val &= 0xdfff;         /* assert DB5           */
1081         outw(*val, tmport);
1082 FUN_D5:
1083         for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns) */
1084                 if ((inw(tmport) & 0x2000) != 0) {      /* DB5 all release?       */
1085                         goto FUN_D5;
1086                 }
1087         }
1088         *val |= 0x8000;         /* no DB4-0, assert DB7    */
1089         *val &= 0xe0ff;
1090         outw(*val, tmport);
1091         *val &= 0xbfff;         /* release DB6             */
1092         outw(*val, tmport);
1093 FUN_D6:
1094         for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns)  */
1095                 if ((inw(tmport) & 0x4000) != 0) {      /* DB6 all release?  */
1096                         goto FUN_D6;
1097                 }
1098         }
1099
1100         return j;
1101 }
1102
1103 static void tscam(struct Scsi_Host *host)
1104 {
1105
1106         unsigned int tmport;
1107         unsigned char i, j, k;
1108         unsigned long n;
1109         unsigned short int m, assignid_map, val;
1110         unsigned char mbuf[33], quintet[2];
1111         struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
1112         static unsigned char g2q_tab[8] = {
1113                 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
1114         };
1115
1116 /*  I can't believe we need this before we've even done anything.  Remove it
1117  *  and see if anyone bitches.
1118         for (i = 0; i < 0x10; i++) {
1119                 udelay(0xffff);
1120         }
1121  */
1122
1123         tmport = dev->ioport[0] + 1;
1124         outb(0x08, tmport++);
1125         outb(0x7f, tmport);
1126         tmport = dev->ioport[0] + 0x11;
1127         outb(0x20, tmport);
1128
1129         if ((dev->scam_on & 0x40) == 0) {
1130                 return;
1131         }
1132         m = 1;
1133         m <<= dev->host_id[0];
1134         j = 16;
1135         if (dev->chip_ver < 4) {
1136                 m |= 0xff00;
1137                 j = 8;
1138         }
1139         assignid_map = m;
1140         tmport = dev->ioport[0] + 0x02;
1141         outb(0x02, tmport++);   /* 2*2=4ms,3EH 2/32*3E=3.9ms */
1142         outb(0, tmport++);
1143         outb(0, tmport++);
1144         outb(0, tmport++);
1145         outb(0, tmport++);
1146         outb(0, tmport++);
1147         outb(0, tmport++);
1148
1149         for (i = 0; i < j; i++) {
1150                 m = 1;
1151                 m = m << i;
1152                 if ((m & assignid_map) != 0) {
1153                         continue;
1154                 }
1155                 tmport = dev->ioport[0] + 0x0f;
1156                 outb(0, tmport++);
1157                 tmport += 0x02;
1158                 outb(0, tmport++);
1159                 outb(0, tmport++);
1160                 outb(0, tmport++);
1161                 if (i > 7) {
1162                         k = (i & 0x07) | 0x40;
1163                 } else {
1164                         k = i;
1165                 }
1166                 outb(k, tmport++);
1167                 tmport = dev->ioport[0] + 0x1b;
1168                 if (dev->chip_ver == 4) {
1169                         outb(0x01, tmport);
1170                 } else {
1171                         outb(0x00, tmport);
1172                 }
1173 wait_rdyok:
1174                 tmport = dev->ioport[0] + 0x18;
1175                 outb(0x09, tmport);
1176                 tmport += 0x07;
1177
1178                 while ((inb(tmport) & 0x80) == 0x00)
1179                         cpu_relax();
1180                 tmport -= 0x08;
1181                 k = inb(tmport);
1182                 if (k != 0x16) {
1183                         if ((k == 0x85) || (k == 0x42)) {
1184                                 continue;
1185                         }
1186                         tmport = dev->ioport[0] + 0x10;
1187                         outb(0x41, tmport);
1188                         goto wait_rdyok;
1189                 }
1190                 assignid_map |= m;
1191
1192         }
1193         tmport = dev->ioport[0] + 0x02;
1194         outb(0x7f, tmport);
1195         tmport = dev->ioport[0] + 0x1b;
1196         outb(0x02, tmport);
1197
1198         outb(0, 0x80);
1199
1200         val = 0x0080;           /* bsy  */
1201         tmport = dev->ioport[0] + 0x1c;
1202         outw(val, tmport);
1203         val |= 0x0040;          /* sel  */
1204         outw(val, tmport);
1205         val |= 0x0004;          /* msg  */
1206         outw(val, tmport);
1207         inb(0x80);              /* 2 deskew delay(45ns*2=90ns) */
1208         val &= 0x007f;          /* no bsy  */
1209         outw(val, tmport);
1210         mdelay(128);
1211         val &= 0x00fb;          /* after 1ms no msg */
1212         outw(val, tmport);
1213 wait_nomsg:
1214         if ((inb(tmport) & 0x04) != 0) {
1215                 goto wait_nomsg;
1216         }
1217         outb(1, 0x80);
1218         udelay(100);
1219         for (n = 0; n < 0x30000; n++) {
1220                 if ((inb(tmport) & 0x80) != 0) {        /* bsy ? */
1221                         goto wait_io;
1222                 }
1223         }
1224         goto TCM_SYNC;
1225 wait_io:
1226         for (n = 0; n < 0x30000; n++) {
1227                 if ((inb(tmport) & 0x81) == 0x0081) {
1228                         goto wait_io1;
1229                 }
1230         }
1231         goto TCM_SYNC;
1232 wait_io1:
1233         inb(0x80);
1234         val |= 0x8003;          /* io,cd,db7  */
1235         outw(val, tmport);
1236         inb(0x80);
1237         val &= 0x00bf;          /* no sel     */
1238         outw(val, tmport);
1239         outb(2, 0x80);
1240 TCM_SYNC:
1241         udelay(0x800);
1242         if ((inb(tmport) & 0x80) == 0x00) {     /* bsy ? */
1243                 outw(0, tmport--);
1244                 outb(0, tmport);
1245                 tmport = dev->ioport[0] + 0x15;
1246                 outb(0, tmport);
1247                 tmport += 0x03;
1248                 outb(0x09, tmport);
1249                 tmport += 0x07;
1250                 while ((inb(tmport) & 0x80) == 0)
1251                         cpu_relax();
1252                 tmport -= 0x08;
1253                 inb(tmport);
1254                 return;
1255         }
1256         val &= 0x00ff;          /* synchronization  */
1257         val |= 0x3f00;
1258         fun_scam(dev, &val);
1259         outb(3, 0x80);
1260         val &= 0x00ff;          /* isolation        */
1261         val |= 0x2000;
1262         fun_scam(dev, &val);
1263         outb(4, 0x80);
1264         i = 8;
1265         j = 0;
1266 TCM_ID:
1267         if ((inw(tmport) & 0x2000) == 0) {
1268                 goto TCM_ID;
1269         }
1270         outb(5, 0x80);
1271         val &= 0x00ff;          /* get ID_STRING */
1272         val |= 0x2000;
1273         k = fun_scam(dev, &val);
1274         if ((k & 0x03) == 0) {
1275                 goto TCM_5;
1276         }
1277         mbuf[j] <<= 0x01;
1278         mbuf[j] &= 0xfe;
1279         if ((k & 0x02) != 0) {
1280                 mbuf[j] |= 0x01;
1281         }
1282         i--;
1283         if (i > 0) {
1284                 goto TCM_ID;
1285         }
1286         j++;
1287         i = 8;
1288         goto TCM_ID;
1289
1290 TCM_5:                  /* isolation complete..  */
1291 /*    mbuf[32]=0;
1292         printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
1293         i = 15;
1294         j = mbuf[0];
1295         if ((j & 0x20) != 0) {  /* bit5=1:ID upto 7      */
1296                 i = 7;
1297         }
1298         if ((j & 0x06) == 0) {  /* IDvalid?             */
1299                 goto G2Q5;
1300         }
1301         k = mbuf[1];
1302 small_id:
1303         m = 1;
1304         m <<= k;
1305         if ((m & assignid_map) == 0) {
1306                 goto G2Q_QUIN;
1307         }
1308         if (k > 0) {
1309                 k--;
1310                 goto small_id;
1311         }
1312 G2Q5:                   /* srch from max acceptable ID#  */
1313         k = i;                  /* max acceptable ID#            */
1314 G2Q_LP:
1315         m = 1;
1316         m <<= k;
1317         if ((m & assignid_map) == 0) {
1318                 goto G2Q_QUIN;
1319         }
1320         if (k > 0) {
1321                 k--;
1322                 goto G2Q_LP;
1323         }
1324 G2Q_QUIN:               /* k=binID#,       */
1325         assignid_map |= m;
1326         if (k < 8) {
1327                 quintet[0] = 0x38;      /* 1st dft ID<8    */
1328         } else {
1329                 quintet[0] = 0x31;      /* 1st  ID>=8      */
1330         }
1331         k &= 0x07;
1332         quintet[1] = g2q_tab[k];
1333
1334         val &= 0x00ff;          /* AssignID 1stQuintet,AH=001xxxxx  */
1335         m = quintet[0] << 8;
1336         val |= m;
1337         fun_scam(dev, &val);
1338         val &= 0x00ff;          /* AssignID 2ndQuintet,AH=001xxxxx */
1339         m = quintet[1] << 8;
1340         val |= m;
1341         fun_scam(dev, &val);
1342
1343         goto TCM_SYNC;
1344
1345 }
1346
1347 static void is870(struct atp_unit *dev, unsigned int wkport)
1348 {
1349         unsigned int tmport;
1350         unsigned char i, j, k, rmb, n;
1351         unsigned short int m;
1352         static unsigned char mbuf[512];
1353         static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1354         static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1355         static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1356         static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
1357         static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
1358         static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1359         
1360         tmport = wkport + 0x3a;
1361         outb((unsigned char) (inb(tmport) | 0x10), tmport);
1362
1363         for (i = 0; i < 16; i++) {
1364                 if ((dev->chip_ver != 4) && (i > 7)) {
1365                         break;
1366                 }
1367                 m = 1;
1368                 m = m << i;
1369                 if ((m & dev->active_id[0]) != 0) {
1370                         continue;
1371                 }
1372                 if (i == dev->host_id[0]) {
1373                         printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
1374                         continue;
1375                 }
1376                 tmport = wkport + 0x1b;
1377                 if (dev->chip_ver == 4) {
1378                         outb(0x01, tmport);
1379                 } else {
1380                         outb(0x00, tmport);
1381                 }
1382                 tmport = wkport + 1;
1383                 outb(0x08, tmport++);
1384                 outb(0x7f, tmport++);
1385                 outb(satn[0], tmport++);
1386                 outb(satn[1], tmport++);
1387                 outb(satn[2], tmport++);
1388                 outb(satn[3], tmport++);
1389                 outb(satn[4], tmport++);
1390                 outb(satn[5], tmport++);
1391                 tmport += 0x06;
1392                 outb(0, tmport);
1393                 tmport += 0x02;
1394                 outb(dev->id[0][i].devsp, tmport++);
1395                 outb(0, tmport++);
1396                 outb(satn[6], tmport++);
1397                 outb(satn[7], tmport++);
1398                 j = i;
1399                 if ((j & 0x08) != 0) {
1400                         j = (j & 0x07) | 0x40;
1401                 }
1402                 outb(j, tmport);
1403                 tmport += 0x03;
1404                 outb(satn[8], tmport);
1405                 tmport += 0x07;
1406
1407                 while ((inb(tmport) & 0x80) == 0x00)
1408                         cpu_relax();
1409
1410                 tmport -= 0x08;
1411                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1412                         continue;
1413
1414                 while (inb(tmport) != 0x8e)
1415                         cpu_relax();
1416
1417                 dev->active_id[0] |= m;
1418
1419                 tmport = wkport + 0x10;
1420                 outb(0x30, tmport);
1421                 tmport = wkport + 0x04;
1422                 outb(0x00, tmport);
1423
1424 phase_cmd:
1425                 tmport = wkport + 0x18;
1426                 outb(0x08, tmport);
1427                 tmport += 0x07;
1428                 while ((inb(tmport) & 0x80) == 0x00)
1429                         cpu_relax();
1430                 tmport -= 0x08;
1431                 j = inb(tmport);
1432                 if (j != 0x16) {
1433                         tmport = wkport + 0x10;
1434                         outb(0x41, tmport);
1435                         goto phase_cmd;
1436                 }
1437 sel_ok:
1438                 tmport = wkport + 3;
1439                 outb(inqd[0], tmport++);
1440                 outb(inqd[1], tmport++);
1441                 outb(inqd[2], tmport++);
1442                 outb(inqd[3], tmport++);
1443                 outb(inqd[4], tmport++);
1444                 outb(inqd[5], tmport);
1445                 tmport += 0x07;
1446                 outb(0, tmport);
1447                 tmport += 0x02;
1448                 outb(dev->id[0][i].devsp, tmport++);
1449                 outb(0, tmport++);
1450                 outb(inqd[6], tmport++);
1451                 outb(inqd[7], tmport++);
1452                 tmport += 0x03;
1453                 outb(inqd[8], tmport);
1454                 tmport += 0x07;
1455
1456                 while ((inb(tmport) & 0x80) == 0x00)
1457                         cpu_relax();
1458                         
1459                 tmport -= 0x08;
1460                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1461                         continue;
1462
1463                 while (inb(tmport) != 0x8e)
1464                         cpu_relax();
1465                         
1466                 tmport = wkport + 0x1b;
1467                 if (dev->chip_ver == 4)
1468                         outb(0x00, tmport);
1469
1470                 tmport = wkport + 0x18;
1471                 outb(0x08, tmport);
1472                 tmport += 0x07;
1473                 j = 0;
1474 rd_inq_data:
1475                 k = inb(tmport);
1476                 if ((k & 0x01) != 0) {
1477                         tmport -= 0x06;
1478                         mbuf[j++] = inb(tmport);
1479                         tmport += 0x06;
1480                         goto rd_inq_data;
1481                 }
1482                 if ((k & 0x80) == 0) {
1483                         goto rd_inq_data;
1484                 }
1485                 tmport -= 0x08;
1486                 j = inb(tmport);
1487                 if (j == 0x16) {
1488                         goto inq_ok;
1489                 }
1490                 tmport = wkport + 0x10;
1491                 outb(0x46, tmport);
1492                 tmport += 0x02;
1493                 outb(0, tmport++);
1494                 outb(0, tmport++);
1495                 outb(0, tmport++);
1496                 tmport += 0x03;
1497                 outb(0x08, tmport);
1498                 tmport += 0x07;
1499
1500                 while ((inb(tmport) & 0x80) == 0x00)
1501                         cpu_relax();
1502                         
1503                 tmport -= 0x08;
1504                 if (inb(tmport) != 0x16) {
1505                         goto sel_ok;
1506                 }
1507 inq_ok:
1508                 mbuf[36] = 0;
1509                 printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
1510                 dev->id[0][i].devtype = mbuf[0];
1511                 rmb = mbuf[1];
1512                 n = mbuf[7];
1513                 if (dev->chip_ver != 4) {
1514                         goto not_wide;
1515                 }
1516                 if ((mbuf[7] & 0x60) == 0) {
1517                         goto not_wide;
1518                 }
1519                 if ((dev->global_map[0] & 0x20) == 0) {
1520                         goto not_wide;
1521                 }
1522                 tmport = wkport + 0x1b;
1523                 outb(0x01, 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[0][i].devsp, 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                         cpu_relax();
1544                         
1545                 tmport -= 0x08;
1546                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1547                         continue;
1548
1549                 while (inb(tmport) != 0x8e)
1550                         cpu_relax();
1551                         
1552 try_wide:
1553                 j = 0;
1554                 tmport = wkport + 0x14;
1555                 outb(0x05, tmport);
1556                 tmport += 0x04;
1557                 outb(0x20, tmport);
1558                 tmport += 0x07;
1559
1560                 while ((inb(tmport) & 0x80) == 0) {
1561                         if ((inb(tmport) & 0x01) != 0) {
1562                                 tmport -= 0x06;
1563                                 outb(wide[j++], tmport);
1564                                 tmport += 0x06;
1565                         }
1566                 }
1567                 tmport -= 0x08;
1568                 
1569                 while ((inb(tmport) & 0x80) == 0x00)
1570                         cpu_relax();
1571                         
1572                 j = inb(tmport) & 0x0f;
1573                 if (j == 0x0f) {
1574                         goto widep_in;
1575                 }
1576                 if (j == 0x0a) {
1577                         goto widep_cmd;
1578                 }
1579                 if (j == 0x0e) {
1580                         goto try_wide;
1581                 }
1582                 continue;
1583 widep_out:
1584                 tmport = wkport + 0x18;
1585                 outb(0x20, tmport);
1586                 tmport += 0x07;
1587                 while ((inb(tmport) & 0x80) == 0) {
1588                         if ((inb(tmport) & 0x01) != 0) {
1589                                 tmport -= 0x06;
1590                                 outb(0, tmport);
1591                                 tmport += 0x06;
1592                         }
1593                 }
1594                 tmport -= 0x08;
1595                 j = inb(tmport) & 0x0f;
1596                 if (j == 0x0f) {
1597                         goto widep_in;
1598                 }
1599                 if (j == 0x0a) {
1600                         goto widep_cmd;
1601                 }
1602                 if (j == 0x0e) {
1603                         goto widep_out;
1604                 }
1605                 continue;
1606 widep_in:
1607                 tmport = wkport + 0x14;
1608                 outb(0xff, tmport);
1609                 tmport += 0x04;
1610                 outb(0x20, tmport);
1611                 tmport += 0x07;
1612                 k = 0;
1613 widep_in1:
1614                 j = inb(tmport);
1615                 if ((j & 0x01) != 0) {
1616                         tmport -= 0x06;
1617                         mbuf[k++] = inb(tmport);
1618                         tmport += 0x06;
1619                         goto widep_in1;
1620                 }
1621                 if ((j & 0x80) == 0x00) {
1622                         goto widep_in1;
1623                 }
1624                 tmport -= 0x08;
1625                 j = inb(tmport) & 0x0f;
1626                 if (j == 0x0f) {
1627                         goto widep_in;
1628                 }
1629                 if (j == 0x0a) {
1630                         goto widep_cmd;
1631                 }
1632                 if (j == 0x0e) {
1633                         goto widep_out;
1634                 }
1635                 continue;
1636 widep_cmd:
1637                 tmport = wkport + 0x10;
1638                 outb(0x30, tmport);
1639                 tmport = wkport + 0x14;
1640                 outb(0x00, tmport);
1641                 tmport += 0x04;
1642                 outb(0x08, tmport);
1643                 tmport += 0x07;
1644                 
1645                 while ((inb(tmport) & 0x80) == 0x00)
1646                         cpu_relax();
1647
1648                 tmport -= 0x08;
1649                 j = inb(tmport);
1650                 if (j != 0x16) {
1651                         if (j == 0x4e) {
1652                                 goto widep_out;
1653                         }
1654                         continue;
1655                 }
1656                 if (mbuf[0] != 0x01) {
1657                         goto not_wide;
1658                 }
1659                 if (mbuf[1] != 0x02) {
1660                         goto not_wide;
1661                 }
1662                 if (mbuf[2] != 0x03) {
1663                         goto not_wide;
1664                 }
1665                 if (mbuf[3] != 0x01) {
1666                         goto not_wide;
1667                 }
1668                 m = 1;
1669                 m = m << i;
1670                 dev->wide_id[0] |= m;
1671 not_wide:
1672                 if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
1673                         goto set_sync;
1674                 }
1675                 continue;
1676 set_sync:
1677                 tmport = wkport + 0x1b;
1678                 j = 0;
1679                 if ((m & dev->wide_id[0]) != 0) {
1680                         j |= 0x01;
1681                 }
1682                 outb(j, tmport);
1683                 tmport = wkport + 3;
1684                 outb(satn[0], tmport++);
1685                 outb(satn[1], tmport++);
1686                 outb(satn[2], tmport++);
1687                 outb(satn[3], tmport++);
1688                 outb(satn[4], tmport++);
1689                 outb(satn[5], tmport++);
1690                 tmport += 0x06;
1691                 outb(0, tmport);
1692                 tmport += 0x02;
1693                 outb(dev->id[0][i].devsp, tmport++);
1694                 outb(0, tmport++);
1695                 outb(satn[6], tmport++);
1696                 outb(satn[7], tmport++);
1697                 tmport += 0x03;
1698                 outb(satn[8], tmport);
1699                 tmport += 0x07;
1700
1701                 while ((inb(tmport) & 0x80) == 0x00)
1702                         cpu_relax();
1703                         
1704                 tmport -= 0x08;
1705                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1706                         continue;
1707
1708                 while (inb(tmport) != 0x8e)
1709                         cpu_relax();
1710                         
1711 try_sync:
1712                 j = 0;
1713                 tmport = wkport + 0x14;
1714                 outb(0x06, tmport);
1715                 tmport += 0x04;
1716                 outb(0x20, tmport);
1717                 tmport += 0x07;
1718
1719                 while ((inb(tmport) & 0x80) == 0) {
1720                         if ((inb(tmport) & 0x01) != 0) {
1721                                 tmport -= 0x06;
1722                                 if ((m & dev->wide_id[0]) != 0) {
1723                                         outb(synw[j++], tmport);
1724                                 } else {
1725                                         if ((m & dev->ultra_map[0]) != 0) {
1726                                                 outb(synu[j++], tmport);
1727                                         } else {
1728                                                 outb(synn[j++], tmport);
1729                                         }
1730                                 }
1731                                 tmport += 0x06;
1732                         }
1733                 }
1734                 tmport -= 0x08;
1735                 
1736                 while ((inb(tmport) & 0x80) == 0x00)
1737                         cpu_relax();
1738                         
1739                 j = inb(tmport) & 0x0f;
1740                 if (j == 0x0f) {
1741                         goto phase_ins;
1742                 }
1743                 if (j == 0x0a) {
1744                         goto phase_cmds;
1745                 }
1746                 if (j == 0x0e) {
1747                         goto try_sync;
1748                 }
1749                 continue;
1750 phase_outs:
1751                 tmport = wkport + 0x18;
1752                 outb(0x20, tmport);
1753                 tmport += 0x07;
1754                 while ((inb(tmport) & 0x80) == 0x00) {
1755                         if ((inb(tmport) & 0x01) != 0x00) {
1756                                 tmport -= 0x06;
1757                                 outb(0x00, tmport);
1758                                 tmport += 0x06;
1759                         }
1760                 }
1761                 tmport -= 0x08;
1762                 j = inb(tmport);
1763                 if (j == 0x85) {
1764                         goto tar_dcons;
1765                 }
1766                 j &= 0x0f;
1767                 if (j == 0x0f) {
1768                         goto phase_ins;
1769                 }
1770                 if (j == 0x0a) {
1771                         goto phase_cmds;
1772                 }
1773                 if (j == 0x0e) {
1774                         goto phase_outs;
1775                 }
1776                 continue;
1777 phase_ins:
1778                 tmport = wkport + 0x14;
1779                 outb(0xff, tmport);
1780                 tmport += 0x04;
1781                 outb(0x20, tmport);
1782                 tmport += 0x07;
1783                 k = 0;
1784 phase_ins1:
1785                 j = inb(tmport);
1786                 if ((j & 0x01) != 0x00) {
1787                         tmport -= 0x06;
1788                         mbuf[k++] = inb(tmport);
1789                         tmport += 0x06;
1790                         goto phase_ins1;
1791                 }
1792                 if ((j & 0x80) == 0x00) {
1793                         goto phase_ins1;
1794                 }
1795                 tmport -= 0x08;
1796
1797                 while ((inb(tmport) & 0x80) == 0x00)
1798                         cpu_relax();
1799                         
1800                 j = inb(tmport);
1801                 if (j == 0x85) {
1802                         goto tar_dcons;
1803                 }
1804                 j &= 0x0f;
1805                 if (j == 0x0f) {
1806                         goto phase_ins;
1807                 }
1808                 if (j == 0x0a) {
1809                         goto phase_cmds;
1810                 }
1811                 if (j == 0x0e) {
1812                         goto phase_outs;
1813                 }
1814                 continue;
1815 phase_cmds:
1816                 tmport = wkport + 0x10;
1817                 outb(0x30, tmport);
1818 tar_dcons:
1819                 tmport = wkport + 0x14;
1820                 outb(0x00, tmport);
1821                 tmport += 0x04;
1822                 outb(0x08, tmport);
1823                 tmport += 0x07;
1824                 
1825                 while ((inb(tmport) & 0x80) == 0x00)
1826                         cpu_relax();
1827                         
1828                 tmport -= 0x08;
1829                 j = inb(tmport);
1830                 if (j != 0x16) {
1831                         continue;
1832                 }
1833                 if (mbuf[0] != 0x01) {
1834                         continue;
1835                 }
1836                 if (mbuf[1] != 0x03) {
1837                         continue;
1838                 }
1839                 if (mbuf[4] == 0x00) {
1840                         continue;
1841                 }
1842                 if (mbuf[3] > 0x64) {
1843                         continue;
1844                 }
1845                 if (mbuf[4] > 0x0c) {
1846                         mbuf[4] = 0x0c;
1847                 }
1848                 dev->id[0][i].devsp = mbuf[4];
1849                 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
1850                         j = 0xa0;
1851                         goto set_syn_ok;
1852                 }
1853                 if (mbuf[3] < 0x1a) {
1854                         j = 0x20;
1855                         goto set_syn_ok;
1856                 }
1857                 if (mbuf[3] < 0x33) {
1858                         j = 0x40;
1859                         goto set_syn_ok;
1860                 }
1861                 if (mbuf[3] < 0x4c) {
1862                         j = 0x50;
1863                         goto set_syn_ok;
1864                 }
1865                 j = 0x60;
1866 set_syn_ok:
1867                 dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
1868         }
1869         tmport = wkport + 0x3a;
1870         outb((unsigned char) (inb(tmport) & 0xef), tmport);
1871 }
1872
1873 static void is880(struct atp_unit *dev, unsigned int wkport)
1874 {
1875         unsigned int tmport;
1876         unsigned char i, j, k, rmb, n, lvdmode;
1877         unsigned short int m;
1878         static unsigned char mbuf[512];
1879         static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
1880         static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
1881         static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1882         unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1883         static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
1884         unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
1885         static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
1886         static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
1887
1888         lvdmode = inb(wkport + 0x3f) & 0x40;
1889
1890         for (i = 0; i < 16; i++) {
1891                 m = 1;
1892                 m = m << i;
1893                 if ((m & dev->active_id[0]) != 0) {
1894                         continue;
1895                 }
1896                 if (i == dev->host_id[0]) {
1897                         printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
1898                         continue;
1899                 }
1900                 tmport = wkport + 0x5b;
1901                 outb(0x01, tmport);
1902                 tmport = wkport + 0x41;
1903                 outb(0x08, tmport++);
1904                 outb(0x7f, tmport++);
1905                 outb(satn[0], tmport++);
1906                 outb(satn[1], tmport++);
1907                 outb(satn[2], tmport++);
1908                 outb(satn[3], tmport++);
1909                 outb(satn[4], tmport++);
1910                 outb(satn[5], tmport++);
1911                 tmport += 0x06;
1912                 outb(0, tmport);
1913                 tmport += 0x02;
1914                 outb(dev->id[0][i].devsp, tmport++);
1915                 outb(0, tmport++);
1916                 outb(satn[6], tmport++);
1917                 outb(satn[7], tmport++);
1918                 j = i;
1919                 if ((j & 0x08) != 0) {
1920                         j = (j & 0x07) | 0x40;
1921                 }
1922                 outb(j, tmport);
1923                 tmport += 0x03;
1924                 outb(satn[8], tmport);
1925                 tmport += 0x07;
1926
1927                 while ((inb(tmport) & 0x80) == 0x00)
1928                         cpu_relax();
1929
1930                 tmport -= 0x08;
1931                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1932                         continue;
1933
1934                 while (inb(tmport) != 0x8e)
1935                         cpu_relax();
1936                         
1937                 dev->active_id[0] |= m;
1938
1939                 tmport = wkport + 0x50;
1940                 outb(0x30, tmport);
1941                 tmport = wkport + 0x54;
1942                 outb(0x00, tmport);
1943
1944 phase_cmd:
1945                 tmport = wkport + 0x58;
1946                 outb(0x08, tmport);
1947                 tmport += 0x07;
1948                 
1949                 while ((inb(tmport) & 0x80) == 0x00)
1950                         cpu_relax();
1951
1952                 tmport -= 0x08;
1953                 j = inb(tmport);
1954                 if (j != 0x16) {
1955                         tmport = wkport + 0x50;
1956                         outb(0x41, tmport);
1957                         goto phase_cmd;
1958                 }
1959 sel_ok:
1960                 tmport = wkport + 0x43;
1961                 outb(inqd[0], tmport++);
1962                 outb(inqd[1], tmport++);
1963                 outb(inqd[2], tmport++);
1964                 outb(inqd[3], tmport++);
1965                 outb(inqd[4], tmport++);
1966                 outb(inqd[5], tmport);
1967                 tmport += 0x07;
1968                 outb(0, tmport);
1969                 tmport += 0x02;
1970                 outb(dev->id[0][i].devsp, tmport++);
1971                 outb(0, tmport++);
1972                 outb(inqd[6], tmport++);
1973                 outb(inqd[7], tmport++);
1974                 tmport += 0x03;
1975                 outb(inqd[8], tmport);
1976                 tmport += 0x07;
1977                 
1978                 while ((inb(tmport) & 0x80) == 0x00)
1979                         cpu_relax();
1980                         
1981                 tmport -= 0x08;
1982                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
1983                         continue;
1984
1985                 while (inb(tmport) != 0x8e)
1986                         cpu_relax();
1987                         
1988                 tmport = wkport + 0x5b;
1989                 outb(0x00, tmport);
1990                 tmport = wkport + 0x58;
1991                 outb(0x08, tmport);
1992                 tmport += 0x07;
1993                 j = 0;
1994 rd_inq_data:
1995                 k = inb(tmport);
1996                 if ((k & 0x01) != 0) {
1997                         tmport -= 0x06;
1998                         mbuf[j++] = inb(tmport);
1999                         tmport += 0x06;
2000                         goto rd_inq_data;
2001                 }
2002                 if ((k & 0x80) == 0) {
2003                         goto rd_inq_data;
2004                 }
2005                 tmport -= 0x08;
2006                 j = inb(tmport);
2007                 if (j == 0x16) {
2008                         goto inq_ok;
2009                 }
2010                 tmport = wkport + 0x50;
2011                 outb(0x46, tmport);
2012                 tmport += 0x02;
2013                 outb(0, tmport++);
2014                 outb(0, tmport++);
2015                 outb(0, tmport++);
2016                 tmport += 0x03;
2017                 outb(0x08, tmport);
2018                 tmport += 0x07;
2019                 while ((inb(tmport) & 0x80) == 0x00)
2020                         cpu_relax();
2021                         
2022                 tmport -= 0x08;
2023                 if (inb(tmport) != 0x16)
2024                         goto sel_ok;
2025
2026 inq_ok:
2027                 mbuf[36] = 0;
2028                 printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
2029                 dev->id[0][i].devtype = mbuf[0];
2030                 rmb = mbuf[1];
2031                 n = mbuf[7];
2032                 if ((mbuf[7] & 0x60) == 0) {
2033                         goto not_wide;
2034                 }
2035                 if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) {
2036                         goto not_wide;
2037                 }
2038                 if (lvdmode == 0) {
2039                         goto chg_wide;
2040                 }
2041                 if (dev->sp[0][i] != 0x04)      // force u2
2042                 {
2043                         goto chg_wide;
2044                 }
2045
2046                 tmport = wkport + 0x5b;
2047                 outb(0x01, tmport);
2048                 tmport = wkport + 0x43;
2049                 outb(satn[0], tmport++);
2050                 outb(satn[1], tmport++);
2051                 outb(satn[2], tmport++);
2052                 outb(satn[3], tmport++);
2053                 outb(satn[4], tmport++);
2054                 outb(satn[5], tmport++);
2055                 tmport += 0x06;
2056                 outb(0, tmport);
2057                 tmport += 0x02;
2058                 outb(dev->id[0][i].devsp, tmport++);
2059                 outb(0, tmport++);
2060                 outb(satn[6], tmport++);
2061                 outb(satn[7], tmport++);
2062                 tmport += 0x03;
2063                 outb(satn[8], tmport);
2064                 tmport += 0x07;
2065
2066                 while ((inb(tmport) & 0x80) == 0x00)
2067                         cpu_relax();
2068
2069                 tmport -= 0x08;
2070
2071                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
2072                         continue;
2073
2074                 while (inb(tmport) != 0x8e)
2075                         cpu_relax();
2076
2077 try_u3:
2078                 j = 0;
2079                 tmport = wkport + 0x54;
2080                 outb(0x09, tmport);
2081                 tmport += 0x04;
2082                 outb(0x20, tmport);
2083                 tmport += 0x07;
2084
2085                 while ((inb(tmport) & 0x80) == 0) {
2086                         if ((inb(tmport) & 0x01) != 0) {
2087                                 tmport -= 0x06;
2088                                 outb(u3[j++], tmport);
2089                                 tmport += 0x06;
2090                         }
2091                 }
2092                 tmport -= 0x08;
2093
2094                 while ((inb(tmport) & 0x80) == 0x00)
2095                         cpu_relax();
2096                         
2097                 j = inb(tmport) & 0x0f;
2098                 if (j == 0x0f) {
2099                         goto u3p_in;
2100                 }
2101                 if (j == 0x0a) {
2102                         goto u3p_cmd;
2103                 }
2104                 if (j == 0x0e) {
2105                         goto try_u3;
2106                 }
2107                 continue;
2108 u3p_out:
2109                 tmport = wkport + 0x58;
2110                 outb(0x20, tmport);
2111                 tmport += 0x07;
2112                 while ((inb(tmport) & 0x80) == 0) {
2113                         if ((inb(tmport) & 0x01) != 0) {
2114                                 tmport -= 0x06;
2115                                 outb(0, tmport);
2116                                 tmport += 0x06;
2117                         }
2118                 }
2119                 tmport -= 0x08;
2120                 j = inb(tmport) & 0x0f;
2121                 if (j == 0x0f) {
2122                         goto u3p_in;
2123                 }
2124                 if (j == 0x0a) {
2125                         goto u3p_cmd;
2126                 }
2127                 if (j == 0x0e) {
2128                         goto u3p_out;
2129                 }
2130                 continue;
2131 u3p_in:
2132                 tmport = wkport + 0x54;
2133                 outb(0x09, tmport);
2134                 tmport += 0x04;
2135                 outb(0x20, tmport);
2136                 tmport += 0x07;
2137                 k = 0;
2138 u3p_in1:
2139                 j = inb(tmport);
2140                 if ((j & 0x01) != 0) {
2141                         tmport -= 0x06;
2142                         mbuf[k++] = inb(tmport);
2143                         tmport += 0x06;
2144                         goto u3p_in1;
2145                 }
2146                 if ((j & 0x80) == 0x00) {
2147                         goto u3p_in1;
2148                 }
2149                 tmport -= 0x08;
2150                 j = inb(tmport) & 0x0f;
2151                 if (j == 0x0f) {
2152                         goto u3p_in;
2153                 }
2154                 if (j == 0x0a) {
2155                         goto u3p_cmd;
2156                 }
2157                 if (j == 0x0e) {
2158                         goto u3p_out;
2159                 }
2160                 continue;
2161 u3p_cmd:
2162                 tmport = wkport + 0x50;
2163                 outb(0x30, tmport);
2164                 tmport = wkport + 0x54;
2165                 outb(0x00, tmport);
2166                 tmport += 0x04;
2167                 outb(0x08, tmport);
2168                 tmport += 0x07;
2169                 
2170                 while ((inb(tmport) & 0x80) == 0x00)
2171                         cpu_relax();
2172                         
2173                 tmport -= 0x08;
2174                 j = inb(tmport);
2175                 if (j != 0x16) {
2176                         if (j == 0x4e) {
2177                                 goto u3p_out;
2178                         }
2179                         continue;
2180                 }
2181                 if (mbuf[0] != 0x01) {
2182                         goto chg_wide;
2183                 }
2184                 if (mbuf[1] != 0x06) {
2185                         goto chg_wide;
2186                 }
2187                 if (mbuf[2] != 0x04) {
2188                         goto chg_wide;
2189                 }
2190                 if (mbuf[3] == 0x09) {
2191                         m = 1;
2192                         m = m << i;
2193                         dev->wide_id[0] |= m;
2194                         dev->id[0][i].devsp = 0xce;
2195                         continue;
2196                 }
2197 chg_wide:
2198                 tmport = wkport + 0x5b;
2199                 outb(0x01, tmport);
2200                 tmport = wkport + 0x43;
2201                 outb(satn[0], tmport++);
2202                 outb(satn[1], tmport++);
2203                 outb(satn[2], tmport++);
2204                 outb(satn[3], tmport++);
2205                 outb(satn[4], tmport++);
2206                 outb(satn[5], tmport++);
2207                 tmport += 0x06;
2208                 outb(0, tmport);
2209                 tmport += 0x02;
2210                 outb(dev->id[0][i].devsp, tmport++);
2211                 outb(0, tmport++);
2212                 outb(satn[6], tmport++);
2213                 outb(satn[7], tmport++);
2214                 tmport += 0x03;
2215                 outb(satn[8], tmport);
2216                 tmport += 0x07;
2217
2218                 while ((inb(tmport) & 0x80) == 0x00)
2219                         cpu_relax();
2220                         
2221                 tmport -= 0x08;
2222                 if (inb(tmport) != 0x11 && inb(tmport) != 0x8e)
2223                         continue;
2224
2225                 while (inb(tmport) != 0x8e)
2226                         cpu_relax();
2227                         
2228 try_wide:
2229                 j = 0;
2230                 tmport = wkport + 0x54;
2231                 outb(0x05, tmport);
2232                 tmport += 0x04;
2233                 outb(0x20, tmport);
2234                 tmport += 0x07;
2235
2236                 while ((inb(tmport) & 0x80) == 0) {
2237                         if ((inb(tmport) & 0x01) != 0) {
2238                                 tmport -= 0x06;
2239                                 outb(wide[j++], tmport);
2240                                 tmport += 0x06;
2241                         }
2242                 }
2243                 tmport -= 0x08;
2244                 while ((inb(tmport) & 0x80) == 0x00)
2245                         cpu_relax();
2246                         
2247                 j = inb(tmport) & 0x0f;
2248                 if (j == 0x0f) {
2249                         goto widep_in;
2250                 }
2251                 if (j == 0x0a) {
2252                         goto widep_cmd;
2253                 }
2254                 if (j == 0x0e) {
2255                         goto try_wide;
2256                 }
2257                 continue;
2258 widep_out:
2259                 tmport = wkport + 0x58;
2260                 outb(0x20, tmport);
2261                 tmport += 0x07;
2262                 while ((inb(tmport) & 0x80) == 0) {
2263                         if ((inb(tmport) & 0x01) != 0) {
2264                                 tmport -= 0x06;
2265                                 outb(0, tmport);
2266                                 tmport += 0x06;
2267                         }
2268                 }
2269                 tmport -= 0x08;
2270                 j = inb(tmport) & 0x0f;
2271                 if (j == 0x0f) {
2272                         goto widep_in;
2273                 }
2274                 if (j == 0x0a) {
2275                         goto widep_cmd;
2276                 }
2277                 if (j == 0x0e) {
2278                         goto widep_out;
2279                 }
2280                 continue;
2281 widep_in:
2282                 tmport = wkport + 0x54;
2283                 outb(0xff, tmport);
2284                 tmport += 0x04;
2285                 outb(0x20, tmport);
2286                 tmport += 0x07;
2287                 k = 0;
2288 widep_in1:
2289                 j = inb(tmport);
2290                 if ((j & 0x01) != 0) {
2291                         tmport -= 0x06;
2292                         mbuf[k++] = inb(tmport);
2293                         tmport += 0x06;
2294                         goto widep_in1;
2295                 }
2296                 if ((j & 0x80) == 0x00) {
2297                         goto widep_in1;
2298                 }
2299                 tmport -= 0x08;
2300                 j = inb(tmport) & 0x0f;
2301                 if (j == 0x0f) {
2302                         goto widep_in;
2303                 }
2304                 if (j == 0x0a) {
2305                         goto widep_cmd;
2306                 }
2307                 if (j == 0x0e) {
2308                         goto widep_out;
2309                 }
2310                 continue;
2311 widep_cmd:
2312                 tmport = wkport + 0x50;
2313                 outb(0x30, tmport);
2314                 tmport = wkport + 0x54;
2315                 outb(0x00, tmport);
2316                 tmport += 0x04;
2317                 outb(0x08, tmport);
2318                 tmport += 0x07;
2319
2320                 while ((inb(tmport) & 0x80) == 0x00)
2321                         cpu_relax();
2322
2323                 tmport -= 0x08;
2324                 j = inb(tmport);
2325                 if (j != 0x16) {
2326                         if (j == 0x4e) {
2327                                 goto widep_out;
2328                         }
2329                         continue;
2330                 }
2331                 if (mbuf[0] != 0x01) {
2332                         goto not_wide;
2333                 }
2334                 if (mbuf[1] != 0x02) {
2335                         goto not_wide;
2336                 }
2337                 if (mbuf[2] != 0x03) {
2338                         goto not_wide;
2339                 }
2340                 if (mbuf[3] != 0x01) {
2341                         goto not_wide;
2342                 }
2343                 m = 1;
2344                 m = m << i;
2345                 dev->wide_id[0] |= m;
2346 not_wide:
2347                 if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
2348                         m = 1;
2349                         m = m << i;
2350                         if ((dev->async[0] & m) != 0) {
2351                                 goto set_sync;
2352                         }
2353                 }
2354                 continue;
2355 set_sync:
2356                 if (dev->sp[0][i] == 0x02) {
2357                         synu[4] = 0x0c;
2358                         synuw[4] = 0x0c;
2359                 } else {
2360                         if (dev->sp[0][i] >= 0x03) {
2361                                 synu[4] = 0x0a;
2362                                 synuw[4] = 0x0a;
2363                         }
2364                 }
2365                 tmport = wkport + 0x5b;
2366                 j = 0;
2367                 if ((m & dev->wide_id[0]) != 0) {
2368                         j |= 0x01;
2369                 }
2370                 outb(j, tmport);
2371                 tmport = wkport + 0x43;
2372                 outb(satn[0], tmport++);
2373                 outb(satn[1], tmport++);
2374                 outb(satn[2], tmport++);
2375                 outb(satn[3], tmport++);
2376                 outb(satn[4], tmport++);
2377                 outb(satn[5], tmport++);
2378                 tmport += 0x06;
2379                 outb(0, tmport);
2380                 tmport += 0x02;
2381                 outb(dev->id[0][i].devsp, tmport++);
2382                 outb(0, tmport++);
2383                 outb(satn[6], tmport++);
2384                 outb(satn[7], tmport++);
2385                 tmport += 0x03;
2386                 outb(satn[8], tmport);
2387                 tmport += 0x07;
2388
2389                 while ((inb(tmport) & 0x80) == 0x00)
2390                         cpu_relax();
2391
2392                 tmport -= 0x08;
2393                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
2394                         continue;
2395                 }
2396                 while (inb(tmport) != 0x8e)
2397                         cpu_relax();
2398
2399 try_sync:
2400                 j = 0;
2401                 tmport = wkport + 0x54;
2402                 outb(0x06, tmport);
2403                 tmport += 0x04;
2404                 outb(0x20, tmport);
2405                 tmport += 0x07;
2406
2407                 while ((inb(tmport) & 0x80) == 0) {
2408                         if ((inb(tmport) & 0x01) != 0) {
2409                                 tmport -= 0x06;
2410                                 if ((m & dev->wide_id[0]) != 0) {
2411                                         if ((m & dev->ultra_map[0]) != 0) {
2412                                                 outb(synuw[j++], tmport);
2413                                         } else {
2414                                                 outb(synw[j++], tmport);
2415                                         }
2416                                 } else {
2417                                         if ((m & dev->ultra_map[0]) != 0) {
2418                                                 outb(synu[j++], tmport);
2419                                         } else {
2420                                                 outb(synn[j++], tmport);
2421                                         }
2422                                 }
2423                                 tmport += 0x06;
2424                         }
2425                 }
2426                 tmport -= 0x08;
2427
2428                 while ((inb(tmport) & 0x80) == 0x00)
2429                         cpu_relax();
2430
2431                 j = inb(tmport) & 0x0f;
2432                 if (j == 0x0f) {
2433                         goto phase_ins;
2434                 }
2435                 if (j == 0x0a) {
2436                         goto phase_cmds;
2437                 }
2438                 if (j == 0x0e) {
2439                         goto try_sync;
2440                 }
2441                 continue;
2442 phase_outs:
2443                 tmport = wkport + 0x58;
2444                 outb(0x20, tmport);
2445                 tmport += 0x07;
2446                 while ((inb(tmport) & 0x80) == 0x00) {
2447                         if ((inb(tmport) & 0x01) != 0x00) {
2448                                 tmport -= 0x06;
2449                                 outb(0x00, tmport);
2450                                 tmport += 0x06;
2451                         }
2452                 }
2453                 tmport -= 0x08;
2454                 j = inb(tmport);
2455                 if (j == 0x85) {
2456                         goto tar_dcons;
2457                 }
2458                 j &= 0x0f;
2459                 if (j == 0x0f) {
2460                         goto phase_ins;
2461                 }
2462                 if (j == 0x0a) {
2463                         goto phase_cmds;
2464                 }
2465                 if (j == 0x0e) {
2466                         goto phase_outs;
2467                 }
2468                 continue;
2469 phase_ins:
2470                 tmport = wkport + 0x54;
2471                 outb(0x06, tmport);
2472                 tmport += 0x04;
2473                 outb(0x20, tmport);
2474                 tmport += 0x07;
2475                 k = 0;
2476 phase_ins1:
2477                 j = inb(tmport);
2478                 if ((j & 0x01) != 0x00) {
2479                         tmport -= 0x06;
2480                         mbuf[k++] = inb(tmport);
2481                         tmport += 0x06;
2482                         goto phase_ins1;
2483                 }
2484                 if ((j & 0x80) == 0x00) {
2485                         goto phase_ins1;
2486                 }
2487                 tmport -= 0x08;
2488
2489                 while ((inb(tmport) & 0x80) == 0x00)
2490                         cpu_relax();
2491
2492                 j = inb(tmport);
2493                 if (j == 0x85) {
2494                         goto tar_dcons;
2495                 }
2496                 j &= 0x0f;
2497                 if (j == 0x0f) {
2498                         goto phase_ins;
2499                 }
2500                 if (j == 0x0a) {
2501                         goto phase_cmds;
2502                 }
2503                 if (j == 0x0e) {
2504                         goto phase_outs;
2505                 }
2506                 continue;
2507 phase_cmds:
2508                 tmport = wkport + 0x50;
2509                 outb(0x30, tmport);
2510 tar_dcons:
2511                 tmport = wkport + 0x54;
2512                 outb(0x00, tmport);
2513                 tmport += 0x04;
2514                 outb(0x08, tmport);
2515                 tmport += 0x07;
2516
2517                 while ((inb(tmport) & 0x80) == 0x00)
2518                         cpu_relax();
2519
2520                 tmport -= 0x08;
2521                 j = inb(tmport);
2522                 if (j != 0x16) {
2523                         continue;
2524                 }
2525                 if (mbuf[0] != 0x01) {
2526                         continue;
2527                 }
2528                 if (mbuf[1] != 0x03) {
2529                         continue;
2530                 }
2531                 if (mbuf[4] == 0x00) {
2532                         continue;
2533                 }
2534                 if (mbuf[3] > 0x64) {
2535                         continue;
2536                 }
2537                 if (mbuf[4] > 0x0e) {
2538                         mbuf[4] = 0x0e;
2539                 }
2540                 dev->id[0][i].devsp = mbuf[4];
2541                 if (mbuf[3] < 0x0c) {
2542                         j = 0xb0;
2543                         goto set_syn_ok;
2544                 }
2545                 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
2546                         j = 0xa0;
2547                         goto set_syn_ok;
2548                 }
2549                 if (mbuf[3] < 0x1a) {
2550                         j = 0x20;
2551                         goto set_syn_ok;
2552                 }
2553                 if (mbuf[3] < 0x33) {
2554                         j = 0x40;
2555                         goto set_syn_ok;
2556                 }
2557                 if (mbuf[3] < 0x4c) {
2558                         j = 0x50;
2559                         goto set_syn_ok;
2560                 }
2561                 j = 0x60;
2562 set_syn_ok:
2563                 dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
2564         }
2565 }
2566
2567 static void atp870u_free_tables(struct Scsi_Host *host)
2568 {
2569         struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2570         int j, k;
2571         for (j=0; j < 2; j++) {
2572                 for (k = 0; k < 16; k++) {
2573                         if (!atp_dev->id[j][k].prd_table)
2574                                 continue;
2575                         pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr);
2576                         atp_dev->id[j][k].prd_table = NULL;
2577                 }
2578         }
2579 }
2580
2581 static int atp870u_init_tables(struct Scsi_Host *host)
2582 {
2583         struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
2584         int c,k;
2585         for(c=0;c < 2;c++) {
2586                 for(k=0;k<16;k++) {
2587                                 atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr));
2588                                 if (!atp_dev->id[c][k].prd_table) {
2589                                         printk("atp870u_init_tables fail\n");
2590                                 atp870u_free_tables(host);
2591                                 return -ENOMEM;
2592                         }
2593                         atp_dev->id[c][k].devsp=0x20;
2594                         atp_dev->id[c][k].devtype = 0x7f;
2595                         atp_dev->id[c][k].curr_req = NULL;                         
2596                 }
2597                                 
2598                 atp_dev->active_id[c] = 0;
2599                 atp_dev->wide_id[c] = 0;
2600                 atp_dev->host_id[c] = 0x07;
2601                 atp_dev->quhd[c] = 0;
2602                 atp_dev->quend[c] = 0;
2603                 atp_dev->last_cmd[c] = 0xff;
2604                 atp_dev->in_snd[c] = 0;
2605                 atp_dev->in_int[c] = 0;
2606                 
2607                 for (k = 0; k < qcnt; k++) {
2608                           atp_dev->quereq[c][k] = NULL;
2609                 }                          
2610                 for (k = 0; k < 16; k++) {
2611                            atp_dev->id[c][k].curr_req = NULL;
2612                            atp_dev->sp[c][k] = 0x04;
2613                 }                  
2614         }
2615         return 0;
2616 }
2617
2618 /* return non-zero on detection */
2619 static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2620 {
2621         unsigned char k, m, c;
2622         unsigned long flags;
2623         unsigned int base_io, tmport, error,n;
2624         unsigned char host_id;
2625         struct Scsi_Host *shpnt = NULL;
2626         struct atp_unit atp_dev, *p;
2627         unsigned char setupdata[2][16];
2628         int count = 0;
2629         
2630         if (pci_enable_device(pdev))
2631                 return -EIO;
2632
2633         if (!pci_set_dma_mask(pdev, 0xFFFFFFFFUL)) {
2634                 printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
2635         } else {
2636                 printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
2637                 return -EIO;
2638         }
2639
2640         memset(&atp_dev, 0, sizeof atp_dev);
2641         /*
2642          * It's probably easier to weed out some revisions like
2643          * this than via the PCI device table
2644          */
2645         if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
2646                 error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
2647                 if (atp_dev.chip_ver < 2)
2648                         return -EIO;
2649         }
2650
2651         switch (ent->device) {
2652         case PCI_DEVICE_ID_ARTOP_AEC7612UW:
2653         case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
2654         case ATP880_DEVID1:     
2655         case ATP880_DEVID2:     
2656         case ATP885_DEVID:      
2657                 atp_dev.chip_ver = 0x04;
2658         default:
2659                 break;
2660         }
2661         base_io = pci_resource_start(pdev, 0);
2662         base_io &= 0xfffffff8;
2663         
2664         if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
2665                 error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
2666                 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
2667
2668                 host_id = inb(base_io + 0x39);
2669                 host_id >>= 0x04;
2670
2671                 printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
2672                         "    IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
2673                 atp_dev.ioport[0] = base_io + 0x40;
2674                 atp_dev.pciport[0] = base_io + 0x28;
2675                 atp_dev.dev_id = ent->device;
2676                 atp_dev.host_id[0] = host_id;
2677
2678                 tmport = base_io + 0x22;
2679                 atp_dev.scam_on = inb(tmport);
2680                 tmport += 0x13;
2681                 atp_dev.global_map[0] = inb(tmport);
2682                 tmport += 0x07;
2683                 atp_dev.ultra_map[0] = inw(tmport);
2684
2685                 n = 0x3f09;
2686 next_fblk_880:
2687                 if (n >= 0x4000)
2688                         goto flash_ok_880;
2689
2690                 m = 0;
2691                 outw(n, base_io + 0x34);
2692                 n += 0x0002;
2693                 if (inb(base_io + 0x30) == 0xff)
2694                         goto flash_ok_880;
2695
2696                 atp_dev.sp[0][m++] = inb(base_io + 0x30);
2697                 atp_dev.sp[0][m++] = inb(base_io + 0x31);
2698                 atp_dev.sp[0][m++] = inb(base_io + 0x32);
2699                 atp_dev.sp[0][m++] = inb(base_io + 0x33);
2700                 outw(n, base_io + 0x34);
2701                 n += 0x0002;
2702                 atp_dev.sp[0][m++] = inb(base_io + 0x30);
2703                 atp_dev.sp[0][m++] = inb(base_io + 0x31);
2704                 atp_dev.sp[0][m++] = inb(base_io + 0x32);
2705                 atp_dev.sp[0][m++] = inb(base_io + 0x33);
2706                 outw(n, base_io + 0x34);
2707                 n += 0x0002;
2708                 atp_dev.sp[0][m++] = inb(base_io + 0x30);
2709                 atp_dev.sp[0][m++] = inb(base_io + 0x31);
2710                 atp_dev.sp[0][m++] = inb(base_io + 0x32);
2711                 atp_dev.sp[0][m++] = inb(base_io + 0x33);
2712                 outw(n, base_io + 0x34);
2713                 n += 0x0002;
2714                 atp_dev.sp[0][m++] = inb(base_io + 0x30);
2715                 atp_dev.sp[0][m++] = inb(base_io + 0x31);
2716                 atp_dev.sp[0][m++] = inb(base_io + 0x32);
2717                 atp_dev.sp[0][m++] = inb(base_io + 0x33);
2718                 n += 0x0018;
2719                 goto next_fblk_880;
2720 flash_ok_880:
2721                 outw(0, base_io + 0x34);
2722                 atp_dev.ultra_map[0] = 0;
2723                 atp_dev.async[0] = 0;
2724                 for (k = 0; k < 16; k++) {
2725                         n = 1;
2726                         n = n << k;
2727                         if (atp_dev.sp[0][k] > 1) {
2728                                 atp_dev.ultra_map[0] |= n;
2729                         } else {
2730                                 if (atp_dev.sp[0][k] == 0)
2731                                         atp_dev.async[0] |= n;
2732                         }
2733                 }
2734                 atp_dev.async[0] = ~(atp_dev.async[0]);
2735                 outb(atp_dev.global_map[0], base_io + 0x35);
2736  
2737                 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2738                 if (!shpnt)
2739                         return -ENOMEM;
2740
2741                 p = (struct atp_unit *)&shpnt->hostdata;
2742
2743                 atp_dev.host = shpnt;
2744                 atp_dev.pdev = pdev;
2745                 pci_set_drvdata(pdev, p);
2746                 memcpy(p, &atp_dev, sizeof atp_dev);
2747                 if (atp870u_init_tables(shpnt) < 0) {
2748                         printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
2749                         goto unregister;
2750                 }
2751
2752                 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp880i", shpnt)) {
2753                         printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
2754                         goto free_tables;
2755                 }
2756
2757                 spin_lock_irqsave(shpnt->host_lock, flags);
2758                 tmport = base_io + 0x38;
2759                 k = inb(tmport) & 0x80;
2760                 outb(k, tmport);
2761                 tmport += 0x03;
2762                 outb(0x20, tmport);
2763                 mdelay(32);
2764                 outb(0, tmport);
2765                 mdelay(32);
2766                 tmport = base_io + 0x5b;
2767                 inb(tmport);
2768                 tmport -= 0x04;
2769                 inb(tmport);
2770                 tmport = base_io + 0x40;
2771                 outb((host_id | 0x08), tmport);
2772                 tmport += 0x18;
2773                 outb(0, tmport);
2774                 tmport += 0x07;
2775                 while ((inb(tmport) & 0x80) == 0)
2776                         mdelay(1);
2777                 tmport -= 0x08;
2778                 inb(tmport);
2779                 tmport = base_io + 0x41;
2780                 outb(8, tmport++);
2781                 outb(0x7f, tmport);
2782                 tmport = base_io + 0x51;
2783                 outb(0x20, tmport);
2784
2785                 tscam(shpnt);
2786                 is880(p, base_io);
2787                 tmport = base_io + 0x38;
2788                 outb(0xb0, tmport);
2789                 shpnt->max_id = 16;
2790                 shpnt->this_id = host_id;
2791                 shpnt->unique_id = base_io;
2792                 shpnt->io_port = base_io;
2793                 shpnt->n_io_port = 0x60;        /* Number of bytes of I/O space used */
2794                 shpnt->irq = pdev->irq;                 
2795         } else if (ent->device == ATP885_DEVID) {       
2796                         printk(KERN_INFO "   ACARD AEC-67162 PCI Ultra3 LVD Host Adapter:  IO:%x, IRQ:%d.\n"
2797                                , base_io, pdev->irq);
2798                 
2799                 atp_dev.pdev = pdev;    
2800                 atp_dev.dev_id  = ent->device;
2801                 atp_dev.baseport = base_io;
2802                 atp_dev.ioport[0] = base_io + 0x80;
2803                 atp_dev.ioport[1] = base_io + 0xc0;
2804                 atp_dev.pciport[0] = base_io + 0x40;
2805                 atp_dev.pciport[1] = base_io + 0x50;
2806                                 
2807                 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2808                 if (!shpnt)
2809                         return -ENOMEM;
2810                 
2811                 p = (struct atp_unit *)&shpnt->hostdata;
2812                 
2813                 atp_dev.host = shpnt;
2814                 atp_dev.pdev = pdev;
2815                 pci_set_drvdata(pdev, p);
2816                 memcpy(p, &atp_dev, sizeof(struct atp_unit));
2817                 if (atp870u_init_tables(shpnt) < 0)
2818                         goto unregister;
2819                         
2820 #ifdef ED_DBGP          
2821         printk("request_irq() shpnt %p hostdata %p\n", shpnt, p);
2822 #endif          
2823                 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) {
2824                                 printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
2825                         goto free_tables;
2826                 }
2827                 
2828                 spin_lock_irqsave(shpnt->host_lock, flags);                                             
2829                                 
2830                 c=inb(base_io + 0x29);
2831                 outb((c | 0x04),base_io + 0x29);
2832                 
2833                 n=0x1f80;
2834 next_fblk_885:
2835                 if (n >= 0x2000) {
2836                    goto flash_ok_885;
2837                 }
2838                 outw(n,base_io + 0x3c);
2839                 if (inl(base_io + 0x38) == 0xffffffff) {
2840                    goto flash_ok_885;
2841                 }
2842                 for (m=0; m < 2; m++) {
2843                     p->global_map[m]= 0;
2844                     for (k=0; k < 4; k++) {
2845                         outw(n++,base_io + 0x3c);
2846                         ((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38);
2847                     }
2848                     for (k=0; k < 4; k++) {
2849                         outw(n++,base_io + 0x3c);
2850                         ((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38);
2851                     }
2852                     n += 8;
2853                 }
2854                 goto next_fblk_885;
2855 flash_ok_885:
2856 #ifdef ED_DBGP
2857                 printk( "Flash Read OK\n");
2858 #endif  
2859                 c=inb(base_io + 0x29);
2860                 outb((c & 0xfb),base_io + 0x29);
2861                 for (c=0;c < 2;c++) {
2862                     p->ultra_map[c]=0;
2863                     p->async[c] = 0;
2864                     for (k=0; k < 16; k++) {
2865                         n=1;
2866                         n = n << k;
2867                         if (p->sp[c][k] > 1) {
2868                            p->ultra_map[c] |= n;
2869                         } else {
2870                            if (p->sp[c][k] == 0) {
2871                               p->async[c] |= n;
2872                            }
2873                         }
2874                     }
2875                     p->async[c] = ~(p->async[c]);
2876
2877                     if (p->global_map[c] == 0) {
2878                        k=setupdata[c][1];
2879                        if ((k & 0x40) != 0)
2880                           p->global_map[c] |= 0x20;
2881                        k &= 0x07;
2882                        p->global_map[c] |= k;
2883                        if ((setupdata[c][2] & 0x04) != 0)
2884                           p->global_map[c] |= 0x08;
2885                        p->host_id[c] = setupdata[c][0] & 0x07;
2886                     }
2887                 }
2888
2889                 k = inb(base_io + 0x28) & 0x8f;
2890                 k |= 0x10;
2891                 outb(k, base_io + 0x28);
2892                 outb(0x80, base_io + 0x41);
2893                 outb(0x80, base_io + 0x51);
2894                 mdelay(100);
2895                 outb(0, base_io + 0x41);
2896                 outb(0, base_io + 0x51);
2897                 mdelay(1000);
2898                 inb(base_io + 0x9b);
2899                 inb(base_io + 0x97);
2900                 inb(base_io + 0xdb);
2901                 inb(base_io + 0xd7);
2902                 tmport = base_io + 0x80;
2903                 k=p->host_id[0];
2904                 if (k > 7)
2905                    k = (k & 0x07) | 0x40;
2906                 k |= 0x08;
2907                 outb(k, tmport);
2908                 tmport += 0x18;
2909                 outb(0, tmport);
2910                 tmport += 0x07;
2911
2912                 while ((inb(tmport) & 0x80) == 0)
2913                         cpu_relax();
2914         
2915                 tmport -= 0x08;
2916                 inb(tmport);
2917                 tmport = base_io + 0x81;
2918                 outb(8, tmport++);
2919                 outb(0x7f, tmport);
2920                 tmport = base_io + 0x91;
2921                 outb(0x20, tmport);
2922
2923                 tmport = base_io + 0xc0;
2924                 k=p->host_id[1];
2925                 if (k > 7)
2926                    k = (k & 0x07) | 0x40;
2927                 k |= 0x08;
2928                 outb(k, tmport);
2929                 tmport += 0x18;
2930                 outb(0, tmport);
2931                 tmport += 0x07;
2932
2933                 while ((inb(tmport) & 0x80) == 0)
2934                         cpu_relax();
2935
2936                 tmport -= 0x08;
2937                 inb(tmport);
2938                 tmport = base_io + 0xc1;
2939                 outb(8, tmport++);
2940                 outb(0x7f, tmport);
2941                 tmport = base_io + 0xd1;
2942                 outb(0x20, tmport);
2943
2944                 tscam_885();
2945                 printk(KERN_INFO "   Scanning Channel A SCSI Device ...\n");
2946                 is885(p, base_io + 0x80, 0);
2947                 printk(KERN_INFO "   Scanning Channel B SCSI Device ...\n");
2948                 is885(p, base_io + 0xc0, 1);
2949
2950                 k = inb(base_io + 0x28) & 0xcf;
2951                 k |= 0xc0;
2952                 outb(k, base_io + 0x28);
2953                 k = inb(base_io + 0x1f) | 0x80;
2954                 outb(k, base_io + 0x1f);
2955                 k = inb(base_io + 0x29) | 0x01;
2956                 outb(k, base_io + 0x29);
2957 #ifdef ED_DBGP
2958                 //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]);
2959 #endif          
2960                 shpnt->max_id = 16;
2961                 shpnt->max_lun = (p->global_map[0] & 0x07) + 1;
2962                 shpnt->max_channel = 1;
2963                 shpnt->this_id = p->host_id[0];
2964                 shpnt->unique_id = base_io;
2965                 shpnt->io_port = base_io;
2966                 shpnt->n_io_port = 0xff;        /* Number of bytes of I/O space used */
2967                 shpnt->irq = pdev->irq;
2968                                 
2969         } else {
2970                 error = pci_read_config_byte(pdev, 0x49, &host_id);
2971
2972                 printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d "
2973                         "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
2974
2975                 atp_dev.ioport[0] = base_io;
2976                 atp_dev.pciport[0] = base_io + 0x20;
2977                 atp_dev.dev_id = ent->device;
2978                 host_id &= 0x07;
2979                 atp_dev.host_id[0] = host_id;
2980                 tmport = base_io + 0x22;
2981                 atp_dev.scam_on = inb(tmport);
2982                 tmport += 0x0b;
2983                 atp_dev.global_map[0] = inb(tmport++);
2984                 atp_dev.ultra_map[0] = inw(tmport);
2985
2986                 if (atp_dev.ultra_map[0] == 0) {
2987                         atp_dev.scam_on = 0x00;
2988                         atp_dev.global_map[0] = 0x20;
2989                         atp_dev.ultra_map[0] = 0xffff;
2990                 }
2991
2992                 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
2993                 if (!shpnt)
2994                         return -ENOMEM;
2995
2996                 p = (struct atp_unit *)&shpnt->hostdata;
2997                 
2998                 atp_dev.host = shpnt;
2999                 atp_dev.pdev = pdev;
3000                 pci_set_drvdata(pdev, p);
3001                 memcpy(p, &atp_dev, sizeof atp_dev);
3002                 if (atp870u_init_tables(shpnt) < 0)
3003                         goto unregister;
3004
3005                 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870i", shpnt)) {
3006                         printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
3007                         goto free_tables;
3008                 }
3009
3010                 spin_lock_irqsave(shpnt->host_lock, flags);
3011                 if (atp_dev.chip_ver > 0x07) {  /* check if atp876 chip then enable terminator */
3012                         tmport = base_io + 0x3e;
3013                         outb(0x00, tmport);
3014                 }
3015  
3016                 tmport = base_io + 0x3a;
3017                 k = (inb(tmport) & 0xf3) | 0x10;
3018                 outb(k, tmport);
3019                 outb((k & 0xdf), tmport);
3020                 mdelay(32);
3021                 outb(k, tmport);
3022                 mdelay(32);
3023                 tmport = base_io;
3024                 outb((host_id | 0x08), tmport);
3025                 tmport += 0x18;
3026                 outb(0, tmport);
3027                 tmport += 0x07;
3028                 while ((inb(tmport) & 0x80) == 0)
3029                         mdelay(1);
3030
3031                 tmport -= 0x08;
3032                 inb(tmport);
3033                 tmport = base_io + 1;
3034                 outb(8, tmport++);
3035                 outb(0x7f, tmport);
3036                 tmport = base_io + 0x11;
3037                 outb(0x20, tmport);
3038
3039                 tscam(shpnt);
3040                 is870(p, base_io);
3041                 tmport = base_io + 0x3a;
3042                 outb((inb(tmport) & 0xef), tmport);
3043                 tmport++;
3044                 outb((inb(tmport) | 0x20), tmport);
3045                 if (atp_dev.chip_ver == 4)
3046                         shpnt->max_id = 16;
3047                 else            
3048                         shpnt->max_id = 7;
3049                 shpnt->this_id = host_id;
3050                 shpnt->unique_id = base_io;
3051                 shpnt->io_port = base_io;
3052                 shpnt->n_io_port = 0x40;        /* Number of bytes of I/O space used */
3053                 shpnt->irq = pdev->irq;         
3054         } 
3055                 spin_unlock_irqrestore(shpnt->host_lock, flags);
3056                 if(ent->device==ATP885_DEVID) {
3057                         if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */
3058                                 goto request_io_fail;
3059                 } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
3060                         if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */
3061                                 goto request_io_fail;
3062                 } else {
3063                         if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */
3064                                 goto request_io_fail;
3065                 }                               
3066                 count++;
3067                 if (scsi_add_host(shpnt, &pdev->dev))
3068                         goto scsi_add_fail;
3069                 scsi_scan_host(shpnt);
3070 #ifdef ED_DBGP                  
3071                 printk("atp870u_prob : exit\n");
3072 #endif          
3073                 return 0;
3074
3075 scsi_add_fail:
3076         printk("atp870u_prob:scsi_add_fail\n");
3077         if(ent->device==ATP885_DEVID) {
3078                 release_region(base_io, 0xff);
3079         } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
3080                 release_region(base_io, 0x60);
3081         } else {
3082                 release_region(base_io, 0x40);
3083         }
3084 request_io_fail:
3085         printk("atp870u_prob:request_io_fail\n");
3086         free_irq(pdev->irq, shpnt);
3087 free_tables:
3088         printk("atp870u_prob:free_table\n");
3089         atp870u_free_tables(shpnt);
3090 unregister:
3091         printk("atp870u_prob:unregister\n");
3092         scsi_host_put(shpnt);
3093         return -1;              
3094 }
3095
3096 /* The abort command does not leave the device in a clean state where
3097    it is available to be used again.  Until this gets worked out, we will
3098    leave it commented out.  */
3099
3100 static int atp870u_abort(struct scsi_cmnd * SCpnt)
3101 {
3102         unsigned char  j, k, c;
3103         struct scsi_cmnd *workrequ;
3104         unsigned int tmport;
3105         struct atp_unit *dev;   
3106         struct Scsi_Host *host;
3107         host = SCpnt->device->host;
3108
3109         dev = (struct atp_unit *)&host->hostdata;
3110         c=SCpnt->device->channel;
3111         printk(" atp870u: abort Channel = %x \n", c);
3112         printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);
3113         printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);
3114         tmport = dev->ioport[c];
3115         for (j = 0; j < 0x18; j++) {
3116                 printk(" r%2x=%2x", j, inb(tmport++));
3117         }
3118         tmport += 0x04;
3119         printk(" r1c=%2x", inb(tmport));
3120         tmport += 0x03;
3121         printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]);
3122         tmport= dev->pciport[c];
3123         printk(" d00=%2x", inb(tmport));
3124         tmport += 0x02;
3125         printk(" d02=%2x", inb(tmport));
3126         for(j=0;j<16;j++) {
3127            if (dev->id[c][j].curr_req != NULL) {
3128                 workrequ = dev->id[c][j].curr_req;
3129                 printk("\n que cdb= ");
3130                 for (k=0; k < workrequ->cmd_len; k++) {
3131                     printk(" %2x ",workrequ->cmnd[k]);
3132                 }
3133                 printk(" last_lenu= %x ",(unsigned int)dev->id[c][j].last_len);
3134            }
3135         }
3136         return SUCCESS;
3137 }
3138
3139 static const char *atp870u_info(struct Scsi_Host *notused)
3140 {
3141         static char buffer[128];
3142
3143         strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac ");
3144
3145         return buffer;
3146 }
3147
3148 #define BLS buffer + len + size
3149 static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
3150                              char **start, off_t offset, int length, int inout)
3151 {
3152         static u8 buff[512];
3153         int size = 0;
3154         int len = 0;
3155         off_t begin = 0;
3156         off_t pos = 0;
3157         
3158         if (inout)      
3159                 return -EINVAL;
3160         if (offset == 0)
3161                 memset(buff, 0, sizeof(buff));
3162         size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n");
3163         len += size;
3164         pos = begin + len;
3165         size = 0;
3166
3167         size += sprintf(BLS, "\n");
3168         size += sprintf(BLS, "Adapter Configuration:\n");
3169         size += sprintf(BLS, "               Base IO: %#.4lx\n", HBAptr->io_port);
3170         size += sprintf(BLS, "                   IRQ: %d\n", HBAptr->irq);
3171         len += size;
3172         pos = begin + len;
3173         
3174         *start = buffer + (offset - begin);     /* Start of wanted data */
3175         len -= (offset - begin);        /* Start slop */
3176         if (len > length) {
3177                 len = length;   /* Ending slop */
3178         }
3179         return (len);
3180 }
3181
3182
3183 static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev,
3184                         sector_t capacity, int *ip)
3185 {
3186         int heads, sectors, cylinders;
3187
3188         heads = 64;
3189         sectors = 32;
3190         cylinders = (unsigned long)capacity / (heads * sectors);
3191         if (cylinders > 1024) {
3192                 heads = 255;
3193                 sectors = 63;
3194                 cylinders = (unsigned long)capacity / (heads * sectors);
3195         }
3196         ip[0] = heads;
3197         ip[1] = sectors;
3198         ip[2] = cylinders;
3199
3200         return 0;
3201 }
3202
3203 static void atp870u_remove (struct pci_dev *pdev)
3204 {       
3205         struct atp_unit *devext = pci_get_drvdata(pdev);
3206         struct Scsi_Host *pshost = devext->host;
3207         
3208         
3209         scsi_remove_host(pshost);
3210         printk(KERN_INFO "free_irq : %d\n",pshost->irq);
3211         free_irq(pshost->irq, pshost);
3212         release_region(pshost->io_port, pshost->n_io_port);
3213         printk(KERN_INFO "atp870u_free_tables : %p\n",pshost);
3214         atp870u_free_tables(pshost);
3215         printk(KERN_INFO "scsi_host_put : %p\n",pshost);
3216         scsi_host_put(pshost);
3217         printk(KERN_INFO "pci_set_drvdata : %p\n",pdev);
3218         pci_set_drvdata(pdev, NULL);    
3219 }
3220 MODULE_LICENSE("GPL");
3221
3222 static struct scsi_host_template atp870u_template = {
3223      .module                    = THIS_MODULE,
3224      .name                      = "atp870u"             /* name */,
3225      .proc_name                 = "atp870u",
3226      .proc_info                 = atp870u_proc_info,
3227      .info                      = atp870u_info          /* info */,
3228      .queuecommand              = atp870u_queuecommand  /* queuecommand */,
3229      .eh_abort_handler          = atp870u_abort         /* abort */,
3230      .bios_param                = atp870u_biosparam     /* biosparm */,
3231      .can_queue                 = qcnt                  /* can_queue */,
3232      .this_id                   = 7                     /* SCSI ID */,
3233      .sg_tablesize              = ATP870U_SCATTER       /*SG_ALL*/ /*SG_NONE*/,
3234      .cmd_per_lun               = ATP870U_CMDLUN                /* commands per lun */,
3235      .use_clustering            = ENABLE_CLUSTERING,
3236      .max_sectors               = ATP870U_MAX_SECTORS,
3237 };
3238
3239 static struct pci_device_id atp870u_id_table[] = {
3240         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID)                   },
3241         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1)                          },
3242         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2)                          },
3243         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610)    },
3244         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW)  },
3245         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U)   },
3246         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S)   },
3247         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D)   },
3248         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) },
3249         { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060)       },
3250         { 0, },
3251 };
3252
3253 MODULE_DEVICE_TABLE(pci, atp870u_id_table);
3254
3255 static struct pci_driver atp870u_driver = {
3256         .id_table       = atp870u_id_table,
3257         .name           = "atp870u",
3258         .probe          = atp870u_probe,
3259         .remove         = __devexit_p(atp870u_remove),
3260 };
3261
3262 static int __init atp870u_init(void)
3263 {
3264 #ifdef ED_DBGP  
3265         printk("atp870u_init: Entry\n");
3266 #endif  
3267         return pci_register_driver(&atp870u_driver);
3268 }
3269
3270 static void __exit atp870u_exit(void)
3271 {
3272 #ifdef ED_DBGP  
3273         printk("atp870u_exit: Entry\n");
3274 #endif
3275         pci_unregister_driver(&atp870u_driver);
3276 }
3277
3278 static void tscam_885(void)
3279 {
3280         unsigned char i;
3281
3282         for (i = 0; i < 0x2; i++) {
3283                 mdelay(300);
3284         }
3285         return;
3286 }
3287
3288
3289
3290 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c)
3291 {
3292         unsigned int tmport;
3293         unsigned char i, j, k, rmb, n, lvdmode;
3294         unsigned short int m;
3295         static unsigned char mbuf[512];
3296         static unsigned char satn[9] =  {0, 0, 0, 0, 0, 0, 0, 6, 6};
3297         static unsigned char inqd[9] =  {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
3298         static unsigned char synn[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
3299         unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
3300         static unsigned char synw[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
3301         unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
3302         static unsigned char wide[6] =  {0x80, 1, 2, 3, 1, 0};
3303         static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
3304
3305         lvdmode=inb(wkport + 0x1b) >> 7;
3306
3307         for (i = 0; i < 16; i++) {
3308                 m = 1;
3309                 m = m << i;
3310                 if ((m & dev->active_id[c]) != 0) {
3311                         continue;
3312                 }
3313                 if (i == dev->host_id[c]) {
3314                         printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[c]);
3315                         continue;
3316                 }
3317                 tmport = wkport + 0x1b;
3318                 outb(0x01, tmport);
3319                 tmport = wkport + 0x01;
3320                 outb(0x08, tmport++);
3321                 outb(0x7f, tmport++);
3322                 outb(satn[0], tmport++);
3323                 outb(satn[1], tmport++);
3324                 outb(satn[2], tmport++);
3325                 outb(satn[3], tmport++);
3326                 outb(satn[4], tmport++);
3327                 outb(satn[5], tmport++);
3328                 tmport += 0x06;
3329                 outb(0, tmport);
3330                 tmport += 0x02;
3331                 outb(dev->id[c][i].devsp, tmport++);
3332                 
3333                 outb(0, tmport++);
3334                 outb(satn[6], tmport++);
3335                 outb(satn[7], tmport++);
3336                 j = i;
3337                 if ((j & 0x08) != 0) {
3338                         j = (j & 0x07) | 0x40;
3339                 }
3340                 outb(j, tmport);
3341                 tmport += 0x03;
3342                 outb(satn[8], tmport);
3343                 tmport += 0x07;
3344
3345                 while ((inb(tmport) & 0x80) == 0x00)
3346                         cpu_relax();
3347                 tmport -= 0x08;
3348                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3349                         continue;
3350                 }
3351                 while (inb(tmport) != 0x8e)
3352                         cpu_relax();
3353                 dev->active_id[c] |= m;
3354
3355                 tmport = wkport + 0x10;
3356                 outb(0x30, tmport);
3357                 tmport = wkport + 0x14;
3358                 outb(0x00, tmport);
3359
3360 phase_cmd:
3361                 tmport = wkport + 0x18;
3362                 outb(0x08, tmport);
3363                 tmport += 0x07;
3364                 while ((inb(tmport) & 0x80) == 0x00)
3365                         cpu_relax();
3366                 tmport -= 0x08;
3367                 j = inb(tmport);
3368                 if (j != 0x16) {
3369                         tmport = wkport + 0x10;
3370                         outb(0x41, tmport);
3371                         goto phase_cmd;
3372                 }
3373 sel_ok:
3374                 tmport = wkport + 0x03;
3375                 outb(inqd[0], tmport++);
3376                 outb(inqd[1], tmport++);
3377                 outb(inqd[2], tmport++);
3378                 outb(inqd[3], tmport++);
3379                 outb(inqd[4], tmport++);
3380                 outb(inqd[5], tmport);
3381                 tmport += 0x07;
3382                 outb(0, tmport);
3383                 tmport += 0x02;
3384                 outb(dev->id[c][i].devsp, tmport++);
3385                 outb(0, tmport++);
3386                 outb(inqd[6], tmport++);
3387                 outb(inqd[7], tmport++);
3388                 tmport += 0x03;
3389                 outb(inqd[8], tmport);
3390                 tmport += 0x07;
3391                 while ((inb(tmport) & 0x80) == 0x00)
3392                         cpu_relax();
3393                 tmport -= 0x08;
3394                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3395                         continue;
3396                 }
3397                 while (inb(tmport) != 0x8e)
3398                         cpu_relax();
3399                 tmport = wkport + 0x1b;
3400                 outb(0x00, tmport);
3401                 tmport = wkport + 0x18;
3402                 outb(0x08, tmport);
3403                 tmport += 0x07;
3404                 j = 0;
3405 rd_inq_data:
3406                 k = inb(tmport);
3407                 if ((k & 0x01) != 0) {
3408                         tmport -= 0x06;
3409                         mbuf[j++] = inb(tmport);
3410                         tmport += 0x06;
3411                         goto rd_inq_data;
3412                 }
3413                 if ((k & 0x80) == 0) {
3414                         goto rd_inq_data;
3415                 }
3416                 tmport -= 0x08;
3417                 j = inb(tmport);
3418                 if (j == 0x16) {
3419                         goto inq_ok;
3420                 }
3421                 tmport = wkport + 0x10;
3422                 outb(0x46, tmport);
3423                 tmport += 0x02;
3424                 outb(0, tmport++);
3425                 outb(0, tmport++);
3426                 outb(0, tmport++);
3427                 tmport += 0x03;
3428                 outb(0x08, tmport);
3429                 tmport += 0x07;
3430                 while ((inb(tmport) & 0x80) == 0x00)
3431                         cpu_relax();
3432                 tmport -= 0x08;
3433                 if (inb(tmport) != 0x16) {
3434                         goto sel_ok;
3435                 }
3436 inq_ok:
3437                 mbuf[36] = 0;
3438                 printk( KERN_INFO"         ID: %2d  %s\n", i, &mbuf[8]);
3439                 dev->id[c][i].devtype = mbuf[0];
3440                 rmb = mbuf[1];
3441                 n = mbuf[7];
3442                 if ((mbuf[7] & 0x60) == 0) {
3443                         goto not_wide;
3444                 }
3445                 if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) {
3446                         goto not_wide;
3447                 }
3448                 if (lvdmode == 0) {
3449                    goto chg_wide;
3450                 }
3451                 if (dev->sp[c][i] != 0x04) {    // force u2
3452                    goto chg_wide;
3453                 }
3454
3455                 tmport = wkport + 0x1b;
3456                 outb(0x01, tmport);
3457                 tmport = wkport + 0x03;
3458                 outb(satn[0], tmport++);
3459                 outb(satn[1], tmport++);
3460                 outb(satn[2], tmport++);
3461                 outb(satn[3], tmport++);
3462                 outb(satn[4], tmport++);
3463                 outb(satn[5], tmport++);
3464                 tmport += 0x06;
3465                 outb(0, tmport);
3466                 tmport += 0x02;
3467                 outb(dev->id[c][i].devsp, tmport++);
3468                 outb(0, tmport++);
3469                 outb(satn[6], tmport++);
3470                 outb(satn[7], tmport++);
3471                 tmport += 0x03;
3472                 outb(satn[8], tmport);
3473                 tmport += 0x07;
3474
3475                 while ((inb(tmport) & 0x80) == 0x00)
3476                         cpu_relax();
3477                 tmport -= 0x08;
3478                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3479                         continue;
3480                 }
3481                 while (inb(tmport) != 0x8e)
3482                         cpu_relax();
3483 try_u3:
3484                 j = 0;
3485                 tmport = wkport + 0x14;
3486                 outb(0x09, tmport);
3487                 tmport += 0x04;
3488                 outb(0x20, tmport);
3489                 tmport += 0x07;
3490
3491                 while ((inb(tmport) & 0x80) == 0) {
3492                         if ((inb(tmport) & 0x01) != 0) {
3493                                 tmport -= 0x06;
3494                                 outb(u3[j++], tmport);
3495                                 tmport += 0x06;
3496                         }
3497                         cpu_relax();
3498                 }
3499                 tmport -= 0x08;
3500                 while ((inb(tmport) & 0x80) == 0x00)
3501                         cpu_relax();
3502                 j = inb(tmport) & 0x0f;
3503                 if (j == 0x0f) {
3504                         goto u3p_in;
3505                 }
3506                 if (j == 0x0a) {
3507                         goto u3p_cmd;
3508                 }
3509                 if (j == 0x0e) {
3510                         goto try_u3;
3511                 }
3512                 continue;
3513 u3p_out:
3514                 tmport = wkport + 0x18;
3515                 outb(0x20, tmport);
3516                 tmport += 0x07;
3517                 while ((inb(tmport) & 0x80) == 0) {
3518                         if ((inb(tmport) & 0x01) != 0) {
3519                                 tmport -= 0x06;
3520                                 outb(0, tmport);
3521                                 tmport += 0x06;
3522                         }
3523                         cpu_relax();
3524                 }
3525                 tmport -= 0x08;
3526                 j = inb(tmport) & 0x0f;
3527                 if (j == 0x0f) {
3528                         goto u3p_in;
3529                 }
3530                 if (j == 0x0a) {
3531                         goto u3p_cmd;
3532                 }
3533                 if (j == 0x0e) {
3534                         goto u3p_out;
3535                 }
3536                 continue;
3537 u3p_in:
3538                 tmport = wkport + 0x14;
3539                 outb(0x09, tmport);
3540                 tmport += 0x04;
3541                 outb(0x20, tmport);
3542                 tmport += 0x07;
3543                 k = 0;
3544 u3p_in1:
3545                 j = inb(tmport);
3546                 if ((j & 0x01) != 0) {
3547                         tmport -= 0x06;
3548                         mbuf[k++] = inb(tmport);
3549                         tmport += 0x06;
3550                         goto u3p_in1;
3551                 }
3552                 if ((j & 0x80) == 0x00) {
3553                         goto u3p_in1;
3554                 }
3555                 tmport -= 0x08;
3556                 j = inb(tmport) & 0x0f;
3557                 if (j == 0x0f) {
3558                         goto u3p_in;
3559                 }
3560                 if (j == 0x0a) {
3561                         goto u3p_cmd;
3562                 }
3563                 if (j == 0x0e) {
3564                         goto u3p_out;
3565                 }
3566                 continue;
3567 u3p_cmd:
3568                 tmport = wkport + 0x10;
3569                 outb(0x30, tmport);
3570                 tmport = wkport + 0x14;
3571                 outb(0x00, tmport);
3572                 tmport += 0x04;
3573                 outb(0x08, tmport);
3574                 tmport += 0x07;
3575                 while ((inb(tmport) & 0x80) == 0x00);
3576                 tmport -= 0x08;
3577                 j = inb(tmport);
3578                 if (j != 0x16) {
3579                         if (j == 0x4e) {
3580                                 goto u3p_out;
3581                         }
3582                         continue;
3583                 }
3584                 if (mbuf[0] != 0x01) {
3585                         goto chg_wide;
3586                 }
3587                 if (mbuf[1] != 0x06) {
3588                         goto chg_wide;
3589                 }
3590                 if (mbuf[2] != 0x04) {
3591                         goto chg_wide;
3592                 }
3593                 if (mbuf[3] == 0x09) {
3594                         m = 1;
3595                         m = m << i;
3596                         dev->wide_id[c] |= m;
3597                         dev->id[c][i].devsp = 0xce;
3598 #ifdef ED_DBGP             
3599                         printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
3600 #endif
3601                         continue;
3602                 }
3603 chg_wide:
3604                 tmport = wkport + 0x1b;
3605                 outb(0x01, tmport);
3606                 tmport = wkport + 0x03;
3607                 outb(satn[0], tmport++);
3608                 outb(satn[1], tmport++);
3609                 outb(satn[2], tmport++);
3610                 outb(satn[3], tmport++);
3611                 outb(satn[4], tmport++);
3612                 outb(satn[5], tmport++);
3613                 tmport += 0x06;
3614                 outb(0, tmport);
3615                 tmport += 0x02;
3616                 outb(dev->id[c][i].devsp, tmport++);
3617                 outb(0, tmport++);
3618                 outb(satn[6], tmport++);
3619                 outb(satn[7], tmport++);
3620                 tmport += 0x03;
3621                 outb(satn[8], tmport);
3622                 tmport += 0x07;
3623
3624                 while ((inb(tmport) & 0x80) == 0x00)
3625                         cpu_relax();
3626                 tmport -= 0x08;
3627                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3628                         continue;
3629                 }
3630                 while (inb(tmport) != 0x8e)
3631                         cpu_relax();
3632 try_wide:
3633                 j = 0;
3634                 tmport = wkport + 0x14;
3635                 outb(0x05, tmport);
3636                 tmport += 0x04;
3637                 outb(0x20, tmport);
3638                 tmport += 0x07;
3639
3640                 while ((inb(tmport) & 0x80) == 0) {
3641                         if ((inb(tmport) & 0x01) != 0) {
3642                                 tmport -= 0x06;
3643                                 outb(wide[j++], tmport);
3644                                 tmport += 0x06;
3645                         }
3646                         cpu_relax();
3647                 }
3648                 tmport -= 0x08;
3649                 while ((inb(tmport) & 0x80) == 0x00)
3650                         cpu_relax();
3651                 j = inb(tmport) & 0x0f;
3652                 if (j == 0x0f) {
3653                         goto widep_in;
3654                 }
3655                 if (j == 0x0a) {
3656                         goto widep_cmd;
3657                 }
3658                 if (j == 0x0e) {
3659                         goto try_wide;
3660                 }
3661                 continue;
3662 widep_out:
3663                 tmport = wkport + 0x18;
3664                 outb(0x20, tmport);
3665                 tmport += 0x07;
3666                 while ((inb(tmport) & 0x80) == 0) {
3667                         if ((inb(tmport) & 0x01) != 0) {
3668                                 tmport -= 0x06;
3669                                 outb(0, tmport);
3670                                 tmport += 0x06;
3671                         }
3672                         cpu_relax();
3673                 }
3674                 tmport -= 0x08;
3675                 j = inb(tmport) & 0x0f;
3676                 if (j == 0x0f) {
3677                         goto widep_in;
3678                 }
3679                 if (j == 0x0a) {
3680                         goto widep_cmd;
3681                 }
3682                 if (j == 0x0e) {
3683                         goto widep_out;
3684                 }
3685                 continue;
3686 widep_in:
3687                 tmport = wkport + 0x14;
3688                 outb(0xff, tmport);
3689                 tmport += 0x04;
3690                 outb(0x20, tmport);
3691                 tmport += 0x07;
3692                 k = 0;
3693 widep_in1:
3694                 j = inb(tmport);
3695                 if ((j & 0x01) != 0) {
3696                         tmport -= 0x06;
3697                         mbuf[k++] = inb(tmport);
3698                         tmport += 0x06;
3699                         goto widep_in1;
3700                 }
3701                 if ((j & 0x80) == 0x00) {
3702                         goto widep_in1;
3703                 }
3704                 tmport -= 0x08;
3705                 j = inb(tmport) & 0x0f;
3706                 if (j == 0x0f) {
3707                         goto widep_in;
3708                 }
3709                 if (j == 0x0a) {
3710                         goto widep_cmd;
3711                 }
3712                 if (j == 0x0e) {
3713                         goto widep_out;
3714                 }
3715                 continue;
3716 widep_cmd:
3717                 tmport = wkport + 0x10;
3718                 outb(0x30, tmport);
3719                 tmport = wkport + 0x14;
3720                 outb(0x00, tmport);
3721                 tmport += 0x04;
3722                 outb(0x08, tmport);
3723                 tmport += 0x07;
3724                 while ((inb(tmport) & 0x80) == 0x00)
3725                         cpu_relax();
3726                 tmport -= 0x08;
3727                 j = inb(tmport);
3728                 if (j != 0x16) {
3729                         if (j == 0x4e) {
3730                                 goto widep_out;
3731                         }
3732                         continue;
3733                 }
3734                 if (mbuf[0] != 0x01) {
3735                         goto not_wide;
3736                 }
3737                 if (mbuf[1] != 0x02) {
3738                         goto not_wide;
3739                 }
3740                 if (mbuf[2] != 0x03) {
3741                         goto not_wide;
3742                 }
3743                 if (mbuf[3] != 0x01) {
3744                         goto not_wide;
3745                 }
3746                 m = 1;
3747                 m = m << i;
3748                 dev->wide_id[c] |= m;
3749 not_wide:
3750                 if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) ||
3751                     ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
3752                         m = 1;
3753                         m = m << i;
3754                         if ((dev->async[c] & m) != 0) {
3755                            goto set_sync;
3756                         }
3757                 }
3758                 continue;
3759 set_sync:
3760                 if (dev->sp[c][i] == 0x02) {
3761                    synu[4]=0x0c;
3762                    synuw[4]=0x0c;
3763                 } else {
3764                    if (dev->sp[c][i] >= 0x03) {
3765                       synu[4]=0x0a;
3766                       synuw[4]=0x0a;
3767                    }
3768                 }
3769                 tmport = wkport + 0x1b;
3770                 j = 0;
3771                 if ((m & dev->wide_id[c]) != 0) {
3772                         j |= 0x01;
3773                 }
3774                 outb(j, tmport);
3775                 tmport = wkport + 0x03;
3776                 outb(satn[0], tmport++);
3777                 outb(satn[1], tmport++);
3778                 outb(satn[2], tmport++);
3779                 outb(satn[3], tmport++);
3780                 outb(satn[4], tmport++);
3781                 outb(satn[5], tmport++);
3782                 tmport += 0x06;
3783                 outb(0, tmport);
3784                 tmport += 0x02;
3785                 outb(dev->id[c][i].devsp, tmport++);
3786                 outb(0, tmport++);
3787                 outb(satn[6], tmport++);
3788                 outb(satn[7], tmport++);
3789                 tmport += 0x03;
3790                 outb(satn[8], tmport);
3791                 tmport += 0x07;
3792
3793                 while ((inb(tmport) & 0x80) == 0x00)
3794                         cpu_relax();
3795                 tmport -= 0x08;
3796                 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
3797                         continue;
3798                 }
3799                 while (inb(tmport) != 0x8e)
3800                         cpu_relax();
3801 try_sync:
3802                 j = 0;
3803                 tmport = wkport + 0x14;
3804                 outb(0x06, tmport);
3805                 tmport += 0x04;
3806                 outb(0x20, tmport);
3807                 tmport += 0x07;
3808
3809                 while ((inb(tmport) & 0x80) == 0) {
3810                         if ((inb(tmport) & 0x01) != 0) {
3811                                 tmport -= 0x06;
3812                                 if ((m & dev->wide_id[c]) != 0) {
3813                                         if ((m & dev->ultra_map[c]) != 0) {
3814                                                 outb(synuw[j++], tmport);
3815                                         } else {
3816                                                 outb(synw[j++], tmport);
3817                                         }
3818                                 } else {
3819                                         if ((m & dev->ultra_map[c]) != 0) {
3820                                                 outb(synu[j++], tmport);
3821                                         } else {
3822                                                 outb(synn[j++], tmport);
3823                                         }
3824                                 }
3825                                 tmport += 0x06;
3826                         }
3827                 }
3828                 tmport -= 0x08;
3829                 while ((inb(tmport) & 0x80) == 0x00)
3830                         cpu_relax();
3831                 j = inb(tmport) & 0x0f;
3832                 if (j == 0x0f) {
3833                         goto phase_ins;
3834                 }
3835                 if (j == 0x0a) {
3836                         goto phase_cmds;
3837                 }
3838                 if (j == 0x0e) {
3839                         goto try_sync;
3840                 }
3841                 continue;
3842 phase_outs:
3843                 tmport = wkport + 0x18;
3844                 outb(0x20, tmport);
3845                 tmport += 0x07;
3846                 while ((inb(tmport) & 0x80) == 0x00) {
3847                         if ((inb(tmport) & 0x01) != 0x00) {
3848                                 tmport -= 0x06;
3849                                 outb(0x00, tmport);
3850                                 tmport += 0x06;
3851                         }
3852                         cpu_relax();
3853                 }
3854                 tmport -= 0x08;
3855                 j = inb(tmport);
3856                 if (j == 0x85) {
3857                         goto tar_dcons;
3858                 }
3859                 j &= 0x0f;
3860                 if (j == 0x0f) {
3861                         goto phase_ins;
3862                 }
3863                 if (j == 0x0a) {
3864                         goto phase_cmds;
3865                 }
3866                 if (j == 0x0e) {
3867                         goto phase_outs;
3868                 }
3869                 continue;
3870 phase_ins:
3871                 tmport = wkport + 0x14;
3872                 outb(0x06, tmport);
3873                 tmport += 0x04;
3874                 outb(0x20, tmport);
3875                 tmport += 0x07;
3876                 k = 0;
3877 phase_ins1:
3878                 j = inb(tmport);
3879                 if ((j & 0x01) != 0x00) {
3880                         tmport -= 0x06;
3881                         mbuf[k++] = inb(tmport);
3882                         tmport += 0x06;
3883                         goto phase_ins1;
3884                 }
3885                 if ((j & 0x80) == 0x00) {
3886                         goto phase_ins1;
3887                 }
3888                 tmport -= 0x08;
3889                 while ((inb(tmport) & 0x80) == 0x00);
3890                 j = inb(tmport);
3891                 if (j == 0x85) {
3892                         goto tar_dcons;
3893                 }
3894                 j &= 0x0f;
3895                 if (j == 0x0f) {
3896                         goto phase_ins;
3897                 }
3898                 if (j == 0x0a) {
3899                         goto phase_cmds;
3900                 }
3901                 if (j == 0x0e) {
3902                         goto phase_outs;
3903                 }
3904                 continue;
3905 phase_cmds:
3906                 tmport = wkport + 0x10;
3907                 outb(0x30, tmport);
3908 tar_dcons:
3909                 tmport = wkport + 0x14;
3910                 outb(0x00, tmport);
3911                 tmport += 0x04;
3912                 outb(0x08, tmport);
3913                 tmport += 0x07;
3914                 while ((inb(tmport) & 0x80) == 0x00)
3915                         cpu_relax();
3916                 tmport -= 0x08;
3917                 j = inb(tmport);
3918                 if (j != 0x16) {
3919                         continue;
3920                 }
3921                 if (mbuf[0] != 0x01) {
3922                         continue;
3923                 }
3924                 if (mbuf[1] != 0x03) {
3925                         continue;
3926                 }
3927                 if (mbuf[4] == 0x00) {
3928                         continue;
3929                 }
3930                 if (mbuf[3] > 0x64) {
3931                         continue;
3932                 }
3933                 if (mbuf[4] > 0x0e) {
3934                         mbuf[4] = 0x0e;
3935                 }
3936                 dev->id[c][i].devsp = mbuf[4];
3937                 if (mbuf[3] < 0x0c){
3938                         j = 0xb0;
3939                         goto set_syn_ok;
3940                 }
3941                 if ((mbuf[3] < 0x0d) && (rmb == 0)) {
3942                         j = 0xa0;
3943                         goto set_syn_ok;
3944                 }
3945                 if (mbuf[3] < 0x1a) {
3946                         j = 0x20;
3947                         goto set_syn_ok;
3948                 }
3949                 if (mbuf[3] < 0x33) {
3950                         j = 0x40;
3951                         goto set_syn_ok;
3952                 }
3953                 if (mbuf[3] < 0x4c) {
3954                         j = 0x50;
3955                         goto set_syn_ok;
3956                 }
3957                 j = 0x60;
3958               set_syn_ok:
3959                 dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
3960 #ifdef ED_DBGP          
3961                 printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
3962 #endif
3963         }
3964         tmport = wkport + 0x16;
3965         outb(0x80, tmport);
3966 }
3967
3968 module_init(atp870u_init);
3969 module_exit(atp870u_exit);
3970