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