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