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