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 scmd_printk(KERN_DEBUG, workreq, "CDB"); 301 for (l = 0; l < workreq->cmd_len; l++) 302 printk(KERN_DEBUG " %x",workreq->cmnd[l]); 303 printk("\n"); 304 #endif 305 306 tmport = workport + 0x0f; 307 outb(lun, tmport); 308 tmport += 0x02; 309 outb(dev->id[c][target_id].devsp, tmport++); 310 adrcnt = dev->id[c][target_id].tran_len; 311 k = dev->id[c][target_id].last_len; 312 313 outb(((unsigned char *) &k)[2], tmport++); 314 outb(((unsigned char *) &k)[1], tmport++); 315 outb(((unsigned char *) &k)[0], tmport++); 316 #ifdef ED_DBGP 317 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)); 318 #endif 319 /* Remap wide */ 320 j = target_id; 321 if (target_id > 7) { 322 j = (j & 0x07) | 0x40; 323 } 324 /* Add direction */ 325 j |= dev->id[c][target_id].dirct; 326 outb(j, tmport++); 327 outb(0x80,tmport); 328 329 /* enable 32 bit fifo transfer */ 330 if (dev->dev_id == ATP885_DEVID) { 331 tmpcip = dev->pciport[c] + 1; 332 i=inb(tmpcip) & 0xf3; 333 //j=workreq->cmnd[0]; 334 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { 335 i |= 0x0c; 336 } 337 outb(i,tmpcip); 338 } else if ((dev->dev_id == ATP880_DEVID1) || 339 (dev->dev_id == ATP880_DEVID2) ) { 340 tmport = workport - 0x05; 341 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { 342 outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); 343 } else { 344 outb((unsigned char) (inb(tmport) & 0x3f), tmport); 345 } 346 } else { 347 tmport = workport + 0x3a; 348 if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { 349 outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); 350 } else { 351 outb((unsigned char) (inb(tmport) & 0xf3), tmport); 352 } 353 } 354 tmport = workport + 0x1b; 355 j = 0; 356 id = 1; 357 id = id << target_id; 358 /* 359 * Is this a wide device 360 */ 361 if ((id & dev->wide_id[c]) != 0) { 362 j |= 0x01; 363 } 364 outb(j, tmport); 365 while ((inb(tmport) & 0x01) != j) { 366 outb(j,tmport); 367 } 368 if (dev->id[c][target_id].last_len == 0) { 369 tmport = workport + 0x18; 370 outb(0x08, tmport); 371 dev->in_int[c] = 0; 372 #ifdef ED_DBGP 373 printk("dev->id[c][target_id].last_len = 0\n"); 374 #endif 375 goto handled; 376 } 377 #ifdef ED_DBGP 378 printk("target_id = %d adrcnt = %d\n",target_id,adrcnt); 379 #endif 380 prd = dev->id[c][target_id].prd_pos; 381 while (adrcnt != 0) { 382 id = ((unsigned short int *)prd)[2]; 383 if (id == 0) { 384 k = 0x10000; 385 } else { 386 k = id; 387 } 388 if (k > adrcnt) { 389 ((unsigned short int *)prd)[2] = (unsigned short int) 390 (k - adrcnt); 391 ((unsigned long *)prd)[0] += adrcnt; 392 adrcnt = 0; 393 dev->id[c][target_id].prd_pos = prd; 394 } else { 395 adrcnt -= k; 396 dev->id[c][target_id].prdaddr += 0x08; 397 prd += 0x08; 398 if (adrcnt == 0) { 399 dev->id[c][target_id].prd_pos = prd; 400 } 401 } 402 } 403 tmpcip = dev->pciport[c] + 0x04; 404 outl(dev->id[c][target_id].prdaddr, tmpcip); 405 #ifdef ED_DBGP 406 printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); 407 #endif 408 if (dev->dev_id == ATP885_DEVID) { 409 tmpcip -= 0x04; 410 } else { 411 tmpcip -= 0x02; 412 outb(0x06, tmpcip); 413 outb(0x00, tmpcip); 414 tmpcip -= 0x02; 415 } 416 tmport = workport + 0x18; 417 /* 418 * Check transfer direction 419 */ 420 if (dev->id[c][target_id].dirct != 0) { 421 outb(0x08, tmport); 422 outb(0x01, tmpcip); 423 dev->in_int[c] = 0; 424 #ifdef ED_DBGP 425 printk("status 0x80 return dirct != 0\n"); 426 #endif 427 goto handled; 428 } 429 outb(0x08, tmport); 430 outb(0x09, tmpcip); 431 dev->in_int[c] = 0; 432 #ifdef ED_DBGP 433 printk("status 0x80 return dirct = 0\n"); 434 #endif 435 goto handled; 436 } 437 438 /* 439 * Current scsi request on this target 440 */ 441 442 workreq = dev->id[c][target_id].curr_req; 443 444 if (i == 0x42) { 445 if ((dev->last_cmd[c] & 0xf0) != 0x40) 446 { 447 dev->last_cmd[c] = 0xff; 448 } 449 errstus = 0x02; 450 workreq->result = errstus; 451 goto go_42; 452 } 453 if (i == 0x16) { 454 if ((dev->last_cmd[c] & 0xf0) != 0x40) { 455 dev->last_cmd[c] = 0xff; 456 } 457 errstus = 0; 458 tmport -= 0x08; 459 errstus = inb(tmport); 460 if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { 461 printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); 462 errstus = 0x02; 463 } 464 workreq->result = errstus; 465 go_42: 466 if (dev->dev_id == ATP885_DEVID) { 467 j = inb(dev->baseport + 0x29) | 0x01; 468 outb(j, dev->baseport + 0x29); 469 } 470 /* 471 * Complete the command 472 */ 473 if (workreq->use_sg) { 474 pci_unmap_sg(dev->pdev, 475 (struct scatterlist *)workreq->buffer, 476 workreq->use_sg, 477 workreq->sc_data_direction); 478 } else if (workreq->request_bufflen && 479 workreq->sc_data_direction != DMA_NONE) { 480 pci_unmap_single(dev->pdev, 481 workreq->SCp.dma_handle, 482 workreq->request_bufflen, 483 workreq->sc_data_direction); 484 } 485 spin_lock_irqsave(dev->host->host_lock, flags); 486 (*workreq->scsi_done) (workreq); 487 #ifdef ED_DBGP 488 printk("workreq->scsi_done\n"); 489 #endif 490 /* 491 * Clear it off the queue 492 */ 493 dev->id[c][target_id].curr_req = NULL; 494 dev->working[c]--; 495 spin_unlock_irqrestore(dev->host->host_lock, flags); 496 /* 497 * Take it back wide 498 */ 499 if (dev->wide_id[c] != 0) { 500 tmport = workport + 0x1b; 501 outb(0x01, tmport); 502 while ((inb(tmport) & 0x01) != 0x01) { 503 outb(0x01, tmport); 504 } 505 } 506 /* 507 * If there is stuff to send and nothing going then send it 508 */ 509 spin_lock_irqsave(dev->host->host_lock, flags); 510 if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) && 511 (dev->in_snd[c] == 0)) { 512 #ifdef ED_DBGP 513 printk("Call sent_s870(scsi_done)\n"); 514 #endif 515 send_s870(dev,c); 516 } 517 spin_unlock_irqrestore(dev->host->host_lock, flags); 518 dev->in_int[c] = 0; 519 goto handled; 520 } 521 if ((dev->last_cmd[c] & 0xf0) != 0x40) { 522 dev->last_cmd[c] = 0xff; 523 } 524 if (i == 0x4f) { 525 i = 0x89; 526 } 527 i &= 0x0f; 528 if (i == 0x09) { 529 tmpcip += 4; 530 outl(dev->id[c][target_id].prdaddr, tmpcip); 531 tmpcip = tmpcip - 2; 532 outb(0x06, tmpcip); 533 outb(0x00, tmpcip); 534 tmpcip = tmpcip - 2; 535 tmport = workport + 0x10; 536 outb(0x41, tmport); 537 if (dev->dev_id == ATP885_DEVID) { 538 tmport += 2; 539 k = dev->id[c][target_id].last_len; 540 outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); 541 outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); 542 outb((unsigned char) (((unsigned char *) (&k))[0]), tmport); 543 dev->id[c][target_id].dirct = 0x00; 544 tmport += 0x04; 545 } else { 546 dev->id[c][target_id].dirct = 0x00; 547 tmport += 0x08; 548 } 549 outb(0x08, tmport); 550 outb(0x09, tmpcip); 551 dev->in_int[c] = 0; 552 goto handled; 553 } 554 if (i == 0x08) { 555 tmpcip += 4; 556 outl(dev->id[c][target_id].prdaddr, tmpcip); 557 tmpcip = tmpcip - 2; 558 outb(0x06, tmpcip); 559 outb(0x00, tmpcip); 560 tmpcip = tmpcip - 2; 561 tmport = workport + 0x10; 562 outb(0x41, tmport); 563 if (dev->dev_id == ATP885_DEVID) { 564 tmport += 2; 565 k = dev->id[c][target_id].last_len; 566 outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); 567 outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); 568 outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++); 569 } else { 570 tmport += 5; 571 } 572 outb((unsigned char) (inb(tmport) | 0x20), tmport); 573 dev->id[c][target_id].dirct = 0x20; 574 tmport += 0x03; 575 outb(0x08, tmport); 576 outb(0x01, tmpcip); 577 dev->in_int[c] = 0; 578 goto handled; 579 } 580 tmport -= 0x07; 581 if (i == 0x0a) { 582 outb(0x30, tmport); 583 } else { 584 outb(0x46, tmport); 585 } 586 dev->id[c][target_id].dirct = 0x00; 587 tmport += 0x02; 588 outb(0x00, tmport++); 589 outb(0x00, tmport++); 590 outb(0x00, tmport++); 591 tmport += 0x03; 592 outb(0x08, tmport); 593 dev->in_int[c] = 0; 594 goto handled; 595 } else { 596 // tmport = workport + 0x17; 597 // inb(tmport); 598 // dev->working[c] = 0; 599 dev->in_int[c] = 0; 600 goto handled; 601 } 602 603 handled: 604 #ifdef ED_DBGP 605 printk("atp870u_intr_handle exit\n"); 606 #endif 607 return IRQ_HANDLED; 608 } 609 /** 610 * atp870u_queuecommand - Queue SCSI command 611 * @req_p: request block 612 * @done: completion function 613 * 614 * Queue a command to the ATP queue. Called with the host lock held. 615 */ 616 static int atp870u_queuecommand(struct scsi_cmnd * req_p, 617 void (*done) (struct scsi_cmnd *)) 618 { 619 unsigned char c; 620 unsigned int tmport,m; 621 struct atp_unit *dev; 622 struct Scsi_Host *host; 623 624 c = scmd_channel(req_p); 625 req_p->sense_buffer[0]=0; 626 req_p->resid = 0; 627 if (scmd_channel(req_p) > 1) { 628 req_p->result = 0x00040000; 629 done(req_p); 630 #ifdef ED_DBGP 631 printk("atp870u_queuecommand : req_p->device->channel > 1\n"); 632 #endif 633 return 0; 634 } 635 636 host = req_p->device->host; 637 dev = (struct atp_unit *)&host->hostdata; 638 639 640 641 m = 1; 642 m = m << scmd_id(req_p); 643 644 /* 645 * Fake a timeout for missing targets 646 */ 647 648 if ((m & dev->active_id[c]) == 0) { 649 req_p->result = 0x00040000; 650 done(req_p); 651 return 0; 652 } 653 654 if (done) { 655 req_p->scsi_done = done; 656 } else { 657 #ifdef ED_DBGP 658 printk( "atp870u_queuecommand: done can't be NULL\n"); 659 #endif 660 req_p->result = 0; 661 done(req_p); 662 return 0; 663 } 664 665 /* 666 * Count new command 667 */ 668 dev->quend[c]++; 669 if (dev->quend[c] >= qcnt) { 670 dev->quend[c] = 0; 671 } 672 673 /* 674 * Check queue state 675 */ 676 if (dev->quhd[c] == dev->quend[c]) { 677 if (dev->quend[c] == 0) { 678 dev->quend[c] = qcnt; 679 } 680 #ifdef ED_DBGP 681 printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n"); 682 #endif 683 dev->quend[c]--; 684 req_p->result = 0x00020000; 685 done(req_p); 686 return 0; 687 } 688 dev->quereq[c][dev->quend[c]] = req_p; 689 tmport = dev->ioport[c] + 0x1c; 690 #ifdef ED_DBGP 691 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]); 692 #endif 693 if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { 694 #ifdef ED_DBGP 695 printk("Call sent_s870(atp870u_queuecommand)\n"); 696 #endif 697 send_s870(dev,c); 698 } 699 #ifdef ED_DBGP 700 printk("atp870u_queuecommand : exit\n"); 701 #endif 702 return 0; 703 } 704 705 /** 706 * send_s870 - send a command to the controller 707 * @host: host 708 * 709 * On entry there is work queued to be done. We move some of that work to the 710 * controller itself. 711 * 712 * Caller holds the host lock. 713 */ 714 static void send_s870(struct atp_unit *dev,unsigned char c) 715 { 716 unsigned int tmport; 717 struct scsi_cmnd *workreq; 718 unsigned int i;//,k; 719 unsigned char j, target_id; 720 unsigned char *prd; 721 unsigned short int tmpcip, w; 722 unsigned long l, bttl = 0; 723 unsigned int workport; 724 struct scatterlist *sgpnt; 725 unsigned long sg_count; 726 727 if (dev->in_snd[c] != 0) { 728 #ifdef ED_DBGP 729 printk("cmnd in_snd\n"); 730 #endif 731 return; 732 } 733 #ifdef ED_DBGP 734 printk("Sent_s870 enter\n"); 735 #endif 736 dev->in_snd[c] = 1; 737 if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) { 738 dev->last_cmd[c] &= 0x0f; 739 workreq = dev->id[c][dev->last_cmd[c]].curr_req; 740 if (workreq != NULL) { /* check NULL pointer */ 741 goto cmd_subp; 742 } 743 dev->last_cmd[c] = 0xff; 744 if (dev->quhd[c] == dev->quend[c]) { 745 dev->in_snd[c] = 0; 746 return ; 747 } 748 } 749 if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { 750 dev->in_snd[c] = 0; 751 return ; 752 } 753 dev->working[c]++; 754 j = dev->quhd[c]; 755 dev->quhd[c]++; 756 if (dev->quhd[c] >= qcnt) { 757 dev->quhd[c] = 0; 758 } 759 workreq = dev->quereq[c][dev->quhd[c]]; 760 if (dev->id[c][scmd_id(workreq)].curr_req == 0) { 761 dev->id[c][scmd_id(workreq)].curr_req = workreq; 762 dev->last_cmd[c] = scmd_id(workreq); 763 goto cmd_subp; 764 } 765 dev->quhd[c] = j; 766 dev->working[c]--; 767 dev->in_snd[c] = 0; 768 return; 769 cmd_subp: 770 workport = dev->ioport[c]; 771 tmport = workport + 0x1f; 772 if ((inb(tmport) & 0xb0) != 0) { 773 goto abortsnd; 774 } 775 tmport = workport + 0x1c; 776 if (inb(tmport) == 0) { 777 goto oktosend; 778 } 779 abortsnd: 780 #ifdef ED_DBGP 781 printk("Abort to Send\n"); 782 #endif 783 dev->last_cmd[c] |= 0x40; 784 dev->in_snd[c] = 0; 785 return; 786 oktosend: 787 #ifdef ED_DBGP 788 printk("OK to Send\n"); 789 scmd_printk(KERN_DEBUG, workreq, "CDB"); 790 for(i=0;i<workreq->cmd_len;i++) { 791 printk(" %x",workreq->cmnd[i]); 792 } 793 printk("\n"); 794 #endif 795 if (dev->dev_id == ATP885_DEVID) { 796 j = inb(dev->baseport + 0x29) & 0xfe; 797 outb(j, dev->baseport + 0x29); 798 dev->r1f[c][scmd_id(workreq)] = 0; 799 } 800 801 if (workreq->cmnd[0] == READ_CAPACITY) { 802 if (workreq->request_bufflen > 8) { 803 workreq->request_bufflen = 0x08; 804 } 805 } 806 if (workreq->cmnd[0] == 0x00) { 807 workreq->request_bufflen = 0; 808 } 809 810 tmport = workport + 0x1b; 811 j = 0; 812 target_id = scmd_id(workreq); 813 814 /* 815 * Wide ? 816 */ 817 w = 1; 818 w = w << target_id; 819 if ((w & dev->wide_id[c]) != 0) { 820 j |= 0x01; 821 } 822 outb(j, tmport); 823 while ((inb(tmport) & 0x01) != j) { 824 outb(j,tmport); 825 #ifdef ED_DBGP 826 printk("send_s870 while loop 1\n"); 827 #endif 828 } 829 /* 830 * Write the command 831 */ 832 833 tmport = workport; 834 outb(workreq->cmd_len, tmport++); 835 outb(0x2c, tmport++); 836 if (dev->dev_id == ATP885_DEVID) { 837 outb(0x7f, tmport++); 838 } else { 839 outb(0xcf, tmport++); 840 } 841 for (i = 0; i < workreq->cmd_len; i++) { 842 outb(workreq->cmnd[i], tmport++); 843 } 844 tmport = workport + 0x0f; 845 outb(workreq->device->lun, tmport); 846 tmport += 0x02; 847 /* 848 * Write the target 849 */ 850 outb(dev->id[c][target_id].devsp, tmport++); 851 #ifdef ED_DBGP 852 printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); 853 #endif 854 /* 855 * Figure out the transfer size 856 */ 857 if (workreq->use_sg) { 858 #ifdef ED_DBGP 859 printk("Using SGL\n"); 860 #endif 861 l = 0; 862 863 sgpnt = (struct scatterlist *) workreq->request_buffer; 864 sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg, 865 workreq->sc_data_direction); 866 867 for (i = 0; i < workreq->use_sg; i++) { 868 if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) { 869 panic("Foooooooood fight!"); 870 } 871 l += sgpnt[i].length; 872 } 873 #ifdef ED_DBGP 874 printk( "send_s870: workreq->use_sg %d, sg_count %d l %8ld\n", workreq->use_sg, sg_count, l); 875 #endif 876 } else if(workreq->request_bufflen && workreq->sc_data_direction != PCI_DMA_NONE) { 877 #ifdef ED_DBGP 878 printk("Not using SGL\n"); 879 #endif 880 workreq->SCp.dma_handle = pci_map_single(dev->pdev, workreq->request_buffer, 881 workreq->request_bufflen, 882 workreq->sc_data_direction); 883 l = workreq->request_bufflen; 884 #ifdef ED_DBGP 885 printk( "send_s870: workreq->use_sg %d, l %8ld\n", workreq->use_sg, l); 886 #endif 887 } else l = 0; 888 /* 889 * Write transfer size 890 */ 891 outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++); 892 outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++); 893 outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++); 894 j = target_id; 895 dev->id[c][j].last_len = l; 896 dev->id[c][j].tran_len = 0; 897 #ifdef ED_DBGP 898 printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len); 899 #endif 900 /* 901 * Flip the wide bits 902 */ 903 if ((j & 0x08) != 0) { 904 j = (j & 0x07) | 0x40; 905 } 906 /* 907 * Check transfer direction 908 */ 909 if (workreq->sc_data_direction == DMA_TO_DEVICE) { 910 outb((unsigned char) (j | 0x20), tmport++); 911 } else { 912 outb(j, tmport++); 913 } 914 outb((unsigned char) (inb(tmport) | 0x80), tmport); 915 outb(0x80, tmport); 916 tmport = workport + 0x1c; 917 dev->id[c][target_id].dirct = 0; 918 if (l == 0) { 919 if (inb(tmport) == 0) { 920 tmport = workport + 0x18; 921 #ifdef ED_DBGP 922 printk("change SCSI_CMD_REG 0x08\n"); 923 #endif 924 outb(0x08, tmport); 925 } else { 926 dev->last_cmd[c] |= 0x40; 927 } 928 dev->in_snd[c] = 0; 929 return; 930 } 931 tmpcip = dev->pciport[c]; 932 prd = dev->id[c][target_id].prd_table; 933 dev->id[c][target_id].prd_pos = prd; 934 935 /* 936 * Now write the request list. Either as scatter/gather or as 937 * a linear chain. 938 */ 939 940 if (workreq->use_sg) { 941 sgpnt = (struct scatterlist *) workreq->request_buffer; 942 i = 0; 943 for (j = 0; j < workreq->use_sg; j++) { 944 bttl = sg_dma_address(&sgpnt[j]); 945 l=sg_dma_len(&sgpnt[j]); 946 #ifdef ED_DBGP 947 printk("1. bttl %x, l %x\n",bttl, l); 948 #endif 949 while (l > 0x10000) { 950 (((u16 *) (prd))[i + 3]) = 0x0000; 951 (((u16 *) (prd))[i + 2]) = 0x0000; 952 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); 953 l -= 0x10000; 954 bttl += 0x10000; 955 i += 0x04; 956 } 957 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); 958 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l); 959 (((u16 *) (prd))[i + 3]) = 0; 960 i += 0x04; 961 } 962 (((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000); 963 #ifdef ED_DBGP 964 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])); 965 printk("2. bttl %x, l %x\n",bttl, l); 966 #endif 967 } else { 968 /* 969 * For a linear request write a chain of blocks 970 */ 971 bttl = workreq->SCp.dma_handle; 972 l = workreq->request_bufflen; 973 i = 0; 974 #ifdef ED_DBGP 975 printk("3. bttl %x, l %x\n",bttl, l); 976 #endif 977 while (l > 0x10000) { 978 (((u16 *) (prd))[i + 3]) = 0x0000; 979 (((u16 *) (prd))[i + 2]) = 0x0000; 980 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); 981 l -= 0x10000; 982 bttl += 0x10000; 983 i += 0x04; 984 } 985 (((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000); 986 (((u16 *) (prd))[i + 2]) = cpu_to_le16(l); 987 (((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); 988 #ifdef ED_DBGP 989 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])); 990 printk("4. bttl %x, l %x\n",bttl, l); 991 #endif 992 993 } 994 tmpcip += 4; 995 #ifdef ED_DBGP 996 printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); 997 #endif 998 dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; 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].prd_bus); 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].prd_bus)); 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].prdaddr = atp_dev->id[c][k].prd_bus; 2594 atp_dev->id[c][k].devsp=0x20; 2595 atp_dev->id[c][k].devtype = 0x7f; 2596 atp_dev->id[c][k].curr_req = NULL; 2597 } 2598 2599 atp_dev->active_id[c] = 0; 2600 atp_dev->wide_id[c] = 0; 2601 atp_dev->host_id[c] = 0x07; 2602 atp_dev->quhd[c] = 0; 2603 atp_dev->quend[c] = 0; 2604 atp_dev->last_cmd[c] = 0xff; 2605 atp_dev->in_snd[c] = 0; 2606 atp_dev->in_int[c] = 0; 2607 2608 for (k = 0; k < qcnt; k++) { 2609 atp_dev->quereq[c][k] = NULL; 2610 } 2611 for (k = 0; k < 16; k++) { 2612 atp_dev->id[c][k].curr_req = NULL; 2613 atp_dev->sp[c][k] = 0x04; 2614 } 2615 } 2616 return 0; 2617 } 2618 2619 /* return non-zero on detection */ 2620 static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 2621 { 2622 unsigned char k, m, c; 2623 unsigned long flags; 2624 unsigned int base_io, tmport, error,n; 2625 unsigned char host_id; 2626 struct Scsi_Host *shpnt = NULL; 2627 struct atp_unit atp_dev, *p; 2628 unsigned char setupdata[2][16]; 2629 int count = 0; 2630 2631 if (pci_enable_device(pdev)) 2632 return -EIO; 2633 2634 if (!pci_set_dma_mask(pdev, 0xFFFFFFFFUL)) { 2635 printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); 2636 } else { 2637 printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); 2638 return -EIO; 2639 } 2640 2641 memset(&atp_dev, 0, sizeof atp_dev); 2642 /* 2643 * It's probably easier to weed out some revisions like 2644 * this than via the PCI device table 2645 */ 2646 if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { 2647 error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); 2648 if (atp_dev.chip_ver < 2) 2649 return -EIO; 2650 } 2651 2652 switch (ent->device) { 2653 case PCI_DEVICE_ID_ARTOP_AEC7612UW: 2654 case PCI_DEVICE_ID_ARTOP_AEC7612SUW: 2655 case ATP880_DEVID1: 2656 case ATP880_DEVID2: 2657 case ATP885_DEVID: 2658 atp_dev.chip_ver = 0x04; 2659 default: 2660 break; 2661 } 2662 base_io = pci_resource_start(pdev, 0); 2663 base_io &= 0xfffffff8; 2664 2665 if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { 2666 error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); 2667 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 2668 2669 host_id = inb(base_io + 0x39); 2670 host_id >>= 0x04; 2671 2672 printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" 2673 " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); 2674 atp_dev.ioport[0] = base_io + 0x40; 2675 atp_dev.pciport[0] = base_io + 0x28; 2676 atp_dev.dev_id = ent->device; 2677 atp_dev.host_id[0] = host_id; 2678 2679 tmport = base_io + 0x22; 2680 atp_dev.scam_on = inb(tmport); 2681 tmport += 0x13; 2682 atp_dev.global_map[0] = inb(tmport); 2683 tmport += 0x07; 2684 atp_dev.ultra_map[0] = inw(tmport); 2685 2686 n = 0x3f09; 2687 next_fblk_880: 2688 if (n >= 0x4000) 2689 goto flash_ok_880; 2690 2691 m = 0; 2692 outw(n, base_io + 0x34); 2693 n += 0x0002; 2694 if (inb(base_io + 0x30) == 0xff) 2695 goto flash_ok_880; 2696 2697 atp_dev.sp[0][m++] = inb(base_io + 0x30); 2698 atp_dev.sp[0][m++] = inb(base_io + 0x31); 2699 atp_dev.sp[0][m++] = inb(base_io + 0x32); 2700 atp_dev.sp[0][m++] = inb(base_io + 0x33); 2701 outw(n, base_io + 0x34); 2702 n += 0x0002; 2703 atp_dev.sp[0][m++] = inb(base_io + 0x30); 2704 atp_dev.sp[0][m++] = inb(base_io + 0x31); 2705 atp_dev.sp[0][m++] = inb(base_io + 0x32); 2706 atp_dev.sp[0][m++] = inb(base_io + 0x33); 2707 outw(n, base_io + 0x34); 2708 n += 0x0002; 2709 atp_dev.sp[0][m++] = inb(base_io + 0x30); 2710 atp_dev.sp[0][m++] = inb(base_io + 0x31); 2711 atp_dev.sp[0][m++] = inb(base_io + 0x32); 2712 atp_dev.sp[0][m++] = inb(base_io + 0x33); 2713 outw(n, base_io + 0x34); 2714 n += 0x0002; 2715 atp_dev.sp[0][m++] = inb(base_io + 0x30); 2716 atp_dev.sp[0][m++] = inb(base_io + 0x31); 2717 atp_dev.sp[0][m++] = inb(base_io + 0x32); 2718 atp_dev.sp[0][m++] = inb(base_io + 0x33); 2719 n += 0x0018; 2720 goto next_fblk_880; 2721 flash_ok_880: 2722 outw(0, base_io + 0x34); 2723 atp_dev.ultra_map[0] = 0; 2724 atp_dev.async[0] = 0; 2725 for (k = 0; k < 16; k++) { 2726 n = 1; 2727 n = n << k; 2728 if (atp_dev.sp[0][k] > 1) { 2729 atp_dev.ultra_map[0] |= n; 2730 } else { 2731 if (atp_dev.sp[0][k] == 0) 2732 atp_dev.async[0] |= n; 2733 } 2734 } 2735 atp_dev.async[0] = ~(atp_dev.async[0]); 2736 outb(atp_dev.global_map[0], base_io + 0x35); 2737 2738 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); 2739 if (!shpnt) 2740 return -ENOMEM; 2741 2742 p = (struct atp_unit *)&shpnt->hostdata; 2743 2744 atp_dev.host = shpnt; 2745 atp_dev.pdev = pdev; 2746 pci_set_drvdata(pdev, p); 2747 memcpy(p, &atp_dev, sizeof atp_dev); 2748 if (atp870u_init_tables(shpnt) < 0) { 2749 printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); 2750 goto unregister; 2751 } 2752 2753 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp880i", shpnt)) { 2754 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); 2755 goto free_tables; 2756 } 2757 2758 spin_lock_irqsave(shpnt->host_lock, flags); 2759 tmport = base_io + 0x38; 2760 k = inb(tmport) & 0x80; 2761 outb(k, tmport); 2762 tmport += 0x03; 2763 outb(0x20, tmport); 2764 mdelay(32); 2765 outb(0, tmport); 2766 mdelay(32); 2767 tmport = base_io + 0x5b; 2768 inb(tmport); 2769 tmport -= 0x04; 2770 inb(tmport); 2771 tmport = base_io + 0x40; 2772 outb((host_id | 0x08), tmport); 2773 tmport += 0x18; 2774 outb(0, tmport); 2775 tmport += 0x07; 2776 while ((inb(tmport) & 0x80) == 0) 2777 mdelay(1); 2778 tmport -= 0x08; 2779 inb(tmport); 2780 tmport = base_io + 0x41; 2781 outb(8, tmport++); 2782 outb(0x7f, tmport); 2783 tmport = base_io + 0x51; 2784 outb(0x20, tmport); 2785 2786 tscam(shpnt); 2787 is880(p, base_io); 2788 tmport = base_io + 0x38; 2789 outb(0xb0, tmport); 2790 shpnt->max_id = 16; 2791 shpnt->this_id = host_id; 2792 shpnt->unique_id = base_io; 2793 shpnt->io_port = base_io; 2794 shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ 2795 shpnt->irq = pdev->irq; 2796 } else if (ent->device == ATP885_DEVID) { 2797 printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" 2798 , base_io, pdev->irq); 2799 2800 atp_dev.pdev = pdev; 2801 atp_dev.dev_id = ent->device; 2802 atp_dev.baseport = base_io; 2803 atp_dev.ioport[0] = base_io + 0x80; 2804 atp_dev.ioport[1] = base_io + 0xc0; 2805 atp_dev.pciport[0] = base_io + 0x40; 2806 atp_dev.pciport[1] = base_io + 0x50; 2807 2808 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); 2809 if (!shpnt) 2810 return -ENOMEM; 2811 2812 p = (struct atp_unit *)&shpnt->hostdata; 2813 2814 atp_dev.host = shpnt; 2815 atp_dev.pdev = pdev; 2816 pci_set_drvdata(pdev, p); 2817 memcpy(p, &atp_dev, sizeof(struct atp_unit)); 2818 if (atp870u_init_tables(shpnt) < 0) 2819 goto unregister; 2820 2821 #ifdef ED_DBGP 2822 printk("request_irq() shpnt %p hostdata %p\n", shpnt, p); 2823 #endif 2824 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) { 2825 printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); 2826 goto free_tables; 2827 } 2828 2829 spin_lock_irqsave(shpnt->host_lock, flags); 2830 2831 c=inb(base_io + 0x29); 2832 outb((c | 0x04),base_io + 0x29); 2833 2834 n=0x1f80; 2835 next_fblk_885: 2836 if (n >= 0x2000) { 2837 goto flash_ok_885; 2838 } 2839 outw(n,base_io + 0x3c); 2840 if (inl(base_io + 0x38) == 0xffffffff) { 2841 goto flash_ok_885; 2842 } 2843 for (m=0; m < 2; m++) { 2844 p->global_map[m]= 0; 2845 for (k=0; k < 4; k++) { 2846 outw(n++,base_io + 0x3c); 2847 ((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38); 2848 } 2849 for (k=0; k < 4; k++) { 2850 outw(n++,base_io + 0x3c); 2851 ((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38); 2852 } 2853 n += 8; 2854 } 2855 goto next_fblk_885; 2856 flash_ok_885: 2857 #ifdef ED_DBGP 2858 printk( "Flash Read OK\n"); 2859 #endif 2860 c=inb(base_io + 0x29); 2861 outb((c & 0xfb),base_io + 0x29); 2862 for (c=0;c < 2;c++) { 2863 p->ultra_map[c]=0; 2864 p->async[c] = 0; 2865 for (k=0; k < 16; k++) { 2866 n=1; 2867 n = n << k; 2868 if (p->sp[c][k] > 1) { 2869 p->ultra_map[c] |= n; 2870 } else { 2871 if (p->sp[c][k] == 0) { 2872 p->async[c] |= n; 2873 } 2874 } 2875 } 2876 p->async[c] = ~(p->async[c]); 2877 2878 if (p->global_map[c] == 0) { 2879 k=setupdata[c][1]; 2880 if ((k & 0x40) != 0) 2881 p->global_map[c] |= 0x20; 2882 k &= 0x07; 2883 p->global_map[c] |= k; 2884 if ((setupdata[c][2] & 0x04) != 0) 2885 p->global_map[c] |= 0x08; 2886 p->host_id[c] = setupdata[c][0] & 0x07; 2887 } 2888 } 2889 2890 k = inb(base_io + 0x28) & 0x8f; 2891 k |= 0x10; 2892 outb(k, base_io + 0x28); 2893 outb(0x80, base_io + 0x41); 2894 outb(0x80, base_io + 0x51); 2895 mdelay(100); 2896 outb(0, base_io + 0x41); 2897 outb(0, base_io + 0x51); 2898 mdelay(1000); 2899 inb(base_io + 0x9b); 2900 inb(base_io + 0x97); 2901 inb(base_io + 0xdb); 2902 inb(base_io + 0xd7); 2903 tmport = base_io + 0x80; 2904 k=p->host_id[0]; 2905 if (k > 7) 2906 k = (k & 0x07) | 0x40; 2907 k |= 0x08; 2908 outb(k, tmport); 2909 tmport += 0x18; 2910 outb(0, tmport); 2911 tmport += 0x07; 2912 2913 while ((inb(tmport) & 0x80) == 0) 2914 cpu_relax(); 2915 2916 tmport -= 0x08; 2917 inb(tmport); 2918 tmport = base_io + 0x81; 2919 outb(8, tmport++); 2920 outb(0x7f, tmport); 2921 tmport = base_io + 0x91; 2922 outb(0x20, tmport); 2923 2924 tmport = base_io + 0xc0; 2925 k=p->host_id[1]; 2926 if (k > 7) 2927 k = (k & 0x07) | 0x40; 2928 k |= 0x08; 2929 outb(k, tmport); 2930 tmport += 0x18; 2931 outb(0, tmport); 2932 tmport += 0x07; 2933 2934 while ((inb(tmport) & 0x80) == 0) 2935 cpu_relax(); 2936 2937 tmport -= 0x08; 2938 inb(tmport); 2939 tmport = base_io + 0xc1; 2940 outb(8, tmport++); 2941 outb(0x7f, tmport); 2942 tmport = base_io + 0xd1; 2943 outb(0x20, tmport); 2944 2945 tscam_885(); 2946 printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); 2947 is885(p, base_io + 0x80, 0); 2948 printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); 2949 is885(p, base_io + 0xc0, 1); 2950 2951 k = inb(base_io + 0x28) & 0xcf; 2952 k |= 0xc0; 2953 outb(k, base_io + 0x28); 2954 k = inb(base_io + 0x1f) | 0x80; 2955 outb(k, base_io + 0x1f); 2956 k = inb(base_io + 0x29) | 0x01; 2957 outb(k, base_io + 0x29); 2958 #ifdef ED_DBGP 2959 //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); 2960 #endif 2961 shpnt->max_id = 16; 2962 shpnt->max_lun = (p->global_map[0] & 0x07) + 1; 2963 shpnt->max_channel = 1; 2964 shpnt->this_id = p->host_id[0]; 2965 shpnt->unique_id = base_io; 2966 shpnt->io_port = base_io; 2967 shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ 2968 shpnt->irq = pdev->irq; 2969 2970 } else { 2971 error = pci_read_config_byte(pdev, 0x49, &host_id); 2972 2973 printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " 2974 "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); 2975 2976 atp_dev.ioport[0] = base_io; 2977 atp_dev.pciport[0] = base_io + 0x20; 2978 atp_dev.dev_id = ent->device; 2979 host_id &= 0x07; 2980 atp_dev.host_id[0] = host_id; 2981 tmport = base_io + 0x22; 2982 atp_dev.scam_on = inb(tmport); 2983 tmport += 0x0b; 2984 atp_dev.global_map[0] = inb(tmport++); 2985 atp_dev.ultra_map[0] = inw(tmport); 2986 2987 if (atp_dev.ultra_map[0] == 0) { 2988 atp_dev.scam_on = 0x00; 2989 atp_dev.global_map[0] = 0x20; 2990 atp_dev.ultra_map[0] = 0xffff; 2991 } 2992 2993 shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); 2994 if (!shpnt) 2995 return -ENOMEM; 2996 2997 p = (struct atp_unit *)&shpnt->hostdata; 2998 2999 atp_dev.host = shpnt; 3000 atp_dev.pdev = pdev; 3001 pci_set_drvdata(pdev, p); 3002 memcpy(p, &atp_dev, sizeof atp_dev); 3003 if (atp870u_init_tables(shpnt) < 0) 3004 goto unregister; 3005 3006 if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870i", shpnt)) { 3007 printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); 3008 goto free_tables; 3009 } 3010 3011 spin_lock_irqsave(shpnt->host_lock, flags); 3012 if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ 3013 tmport = base_io + 0x3e; 3014 outb(0x00, tmport); 3015 } 3016 3017 tmport = base_io + 0x3a; 3018 k = (inb(tmport) & 0xf3) | 0x10; 3019 outb(k, tmport); 3020 outb((k & 0xdf), tmport); 3021 mdelay(32); 3022 outb(k, tmport); 3023 mdelay(32); 3024 tmport = base_io; 3025 outb((host_id | 0x08), tmport); 3026 tmport += 0x18; 3027 outb(0, tmport); 3028 tmport += 0x07; 3029 while ((inb(tmport) & 0x80) == 0) 3030 mdelay(1); 3031 3032 tmport -= 0x08; 3033 inb(tmport); 3034 tmport = base_io + 1; 3035 outb(8, tmport++); 3036 outb(0x7f, tmport); 3037 tmport = base_io + 0x11; 3038 outb(0x20, tmport); 3039 3040 tscam(shpnt); 3041 is870(p, base_io); 3042 tmport = base_io + 0x3a; 3043 outb((inb(tmport) & 0xef), tmport); 3044 tmport++; 3045 outb((inb(tmport) | 0x20), tmport); 3046 if (atp_dev.chip_ver == 4) 3047 shpnt->max_id = 16; 3048 else 3049 shpnt->max_id = 7; 3050 shpnt->this_id = host_id; 3051 shpnt->unique_id = base_io; 3052 shpnt->io_port = base_io; 3053 shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ 3054 shpnt->irq = pdev->irq; 3055 } 3056 spin_unlock_irqrestore(shpnt->host_lock, flags); 3057 if(ent->device==ATP885_DEVID) { 3058 if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */ 3059 goto request_io_fail; 3060 } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { 3061 if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */ 3062 goto request_io_fail; 3063 } else { 3064 if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */ 3065 goto request_io_fail; 3066 } 3067 count++; 3068 if (scsi_add_host(shpnt, &pdev->dev)) 3069 goto scsi_add_fail; 3070 scsi_scan_host(shpnt); 3071 #ifdef ED_DBGP 3072 printk("atp870u_prob : exit\n"); 3073 #endif 3074 return 0; 3075 3076 scsi_add_fail: 3077 printk("atp870u_prob:scsi_add_fail\n"); 3078 if(ent->device==ATP885_DEVID) { 3079 release_region(base_io, 0xff); 3080 } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { 3081 release_region(base_io, 0x60); 3082 } else { 3083 release_region(base_io, 0x40); 3084 } 3085 request_io_fail: 3086 printk("atp870u_prob:request_io_fail\n"); 3087 free_irq(pdev->irq, shpnt); 3088 free_tables: 3089 printk("atp870u_prob:free_table\n"); 3090 atp870u_free_tables(shpnt); 3091 unregister: 3092 printk("atp870u_prob:unregister\n"); 3093 scsi_host_put(shpnt); 3094 return -1; 3095 } 3096 3097 /* The abort command does not leave the device in a clean state where 3098 it is available to be used again. Until this gets worked out, we will 3099 leave it commented out. */ 3100 3101 static int atp870u_abort(struct scsi_cmnd * SCpnt) 3102 { 3103 unsigned char j, k, c; 3104 struct scsi_cmnd *workrequ; 3105 unsigned int tmport; 3106 struct atp_unit *dev; 3107 struct Scsi_Host *host; 3108 host = SCpnt->device->host; 3109 3110 dev = (struct atp_unit *)&host->hostdata; 3111 c = scmd_channel(SCpnt); 3112 printk(" atp870u: abort Channel = %x \n", c); 3113 printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); 3114 printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); 3115 tmport = dev->ioport[c]; 3116 for (j = 0; j < 0x18; j++) { 3117 printk(" r%2x=%2x", j, inb(tmport++)); 3118 } 3119 tmport += 0x04; 3120 printk(" r1c=%2x", inb(tmport)); 3121 tmport += 0x03; 3122 printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]); 3123 tmport= dev->pciport[c]; 3124 printk(" d00=%2x", inb(tmport)); 3125 tmport += 0x02; 3126 printk(" d02=%2x", inb(tmport)); 3127 for(j=0;j<16;j++) { 3128 if (dev->id[c][j].curr_req != NULL) { 3129 workrequ = dev->id[c][j].curr_req; 3130 printk("\n que cdb= "); 3131 for (k=0; k < workrequ->cmd_len; k++) { 3132 printk(" %2x ",workrequ->cmnd[k]); 3133 } 3134 printk(" last_lenu= %x ",(unsigned int)dev->id[c][j].last_len); 3135 } 3136 } 3137 return SUCCESS; 3138 } 3139 3140 static const char *atp870u_info(struct Scsi_Host *notused) 3141 { 3142 static char buffer[128]; 3143 3144 strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.6+ac "); 3145 3146 return buffer; 3147 } 3148 3149 #define BLS buffer + len + size 3150 static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 3151 char **start, off_t offset, int length, int inout) 3152 { 3153 static u8 buff[512]; 3154 int size = 0; 3155 int len = 0; 3156 off_t begin = 0; 3157 off_t pos = 0; 3158 3159 if (inout) 3160 return -EINVAL; 3161 if (offset == 0) 3162 memset(buff, 0, sizeof(buff)); 3163 size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.6+ac\n"); 3164 len += size; 3165 pos = begin + len; 3166 size = 0; 3167 3168 size += sprintf(BLS, "\n"); 3169 size += sprintf(BLS, "Adapter Configuration:\n"); 3170 size += sprintf(BLS, " Base IO: %#.4lx\n", HBAptr->io_port); 3171 size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); 3172 len += size; 3173 pos = begin + len; 3174 3175 *start = buffer + (offset - begin); /* Start of wanted data */ 3176 len -= (offset - begin); /* Start slop */ 3177 if (len > length) { 3178 len = length; /* Ending slop */ 3179 } 3180 return (len); 3181 } 3182 3183 3184 static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev, 3185 sector_t capacity, int *ip) 3186 { 3187 int heads, sectors, cylinders; 3188 3189 heads = 64; 3190 sectors = 32; 3191 cylinders = (unsigned long)capacity / (heads * sectors); 3192 if (cylinders > 1024) { 3193 heads = 255; 3194 sectors = 63; 3195 cylinders = (unsigned long)capacity / (heads * sectors); 3196 } 3197 ip[0] = heads; 3198 ip[1] = sectors; 3199 ip[2] = cylinders; 3200 3201 return 0; 3202 } 3203 3204 static void atp870u_remove (struct pci_dev *pdev) 3205 { 3206 struct atp_unit *devext = pci_get_drvdata(pdev); 3207 struct Scsi_Host *pshost = devext->host; 3208 3209 3210 scsi_remove_host(pshost); 3211 printk(KERN_INFO "free_irq : %d\n",pshost->irq); 3212 free_irq(pshost->irq, pshost); 3213 release_region(pshost->io_port, pshost->n_io_port); 3214 printk(KERN_INFO "atp870u_free_tables : %p\n",pshost); 3215 atp870u_free_tables(pshost); 3216 printk(KERN_INFO "scsi_host_put : %p\n",pshost); 3217 scsi_host_put(pshost); 3218 printk(KERN_INFO "pci_set_drvdata : %p\n",pdev); 3219 pci_set_drvdata(pdev, NULL); 3220 } 3221 MODULE_LICENSE("GPL"); 3222 3223 static struct scsi_host_template atp870u_template = { 3224 .module = THIS_MODULE, 3225 .name = "atp870u" /* name */, 3226 .proc_name = "atp870u", 3227 .proc_info = atp870u_proc_info, 3228 .info = atp870u_info /* info */, 3229 .queuecommand = atp870u_queuecommand /* queuecommand */, 3230 .eh_abort_handler = atp870u_abort /* abort */, 3231 .bios_param = atp870u_biosparam /* biosparm */, 3232 .can_queue = qcnt /* can_queue */, 3233 .this_id = 7 /* SCSI ID */, 3234 .sg_tablesize = ATP870U_SCATTER /*SG_ALL*/ /*SG_NONE*/, 3235 .cmd_per_lun = ATP870U_CMDLUN /* commands per lun */, 3236 .use_clustering = ENABLE_CLUSTERING, 3237 .max_sectors = ATP870U_MAX_SECTORS, 3238 }; 3239 3240 static struct pci_device_id atp870u_id_table[] = { 3241 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID) }, 3242 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1) }, 3243 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2) }, 3244 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) }, 3245 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) }, 3246 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) }, 3247 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612S) }, 3248 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612D) }, 3249 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612SUW) }, 3250 { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_8060) }, 3251 { 0, }, 3252 }; 3253 3254 MODULE_DEVICE_TABLE(pci, atp870u_id_table); 3255 3256 static struct pci_driver atp870u_driver = { 3257 .id_table = atp870u_id_table, 3258 .name = "atp870u", 3259 .probe = atp870u_probe, 3260 .remove = __devexit_p(atp870u_remove), 3261 }; 3262 3263 static int __init atp870u_init(void) 3264 { 3265 #ifdef ED_DBGP 3266 printk("atp870u_init: Entry\n"); 3267 #endif 3268 return pci_register_driver(&atp870u_driver); 3269 } 3270 3271 static void __exit atp870u_exit(void) 3272 { 3273 #ifdef ED_DBGP 3274 printk("atp870u_exit: Entry\n"); 3275 #endif 3276 pci_unregister_driver(&atp870u_driver); 3277 } 3278 3279 static void tscam_885(void) 3280 { 3281 unsigned char i; 3282 3283 for (i = 0; i < 0x2; i++) { 3284 mdelay(300); 3285 } 3286 return; 3287 } 3288 3289 3290 3291 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) 3292 { 3293 unsigned int tmport; 3294 unsigned char i, j, k, rmb, n, lvdmode; 3295 unsigned short int m; 3296 static unsigned char mbuf[512]; 3297 static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6}; 3298 static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6}; 3299 static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; 3300 unsigned char synu[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; 3301 static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; 3302 unsigned char synuw[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; 3303 static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; 3304 static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; 3305 3306 lvdmode=inb(wkport + 0x1b) >> 7; 3307 3308 for (i = 0; i < 16; i++) { 3309 m = 1; 3310 m = m << i; 3311 if ((m & dev->active_id[c]) != 0) { 3312 continue; 3313 } 3314 if (i == dev->host_id[c]) { 3315 printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); 3316 continue; 3317 } 3318 tmport = wkport + 0x1b; 3319 outb(0x01, tmport); 3320 tmport = wkport + 0x01; 3321 outb(0x08, tmport++); 3322 outb(0x7f, tmport++); 3323 outb(satn[0], tmport++); 3324 outb(satn[1], tmport++); 3325 outb(satn[2], tmport++); 3326 outb(satn[3], tmport++); 3327 outb(satn[4], tmport++); 3328 outb(satn[5], tmport++); 3329 tmport += 0x06; 3330 outb(0, tmport); 3331 tmport += 0x02; 3332 outb(dev->id[c][i].devsp, tmport++); 3333 3334 outb(0, tmport++); 3335 outb(satn[6], tmport++); 3336 outb(satn[7], tmport++); 3337 j = i; 3338 if ((j & 0x08) != 0) { 3339 j = (j & 0x07) | 0x40; 3340 } 3341 outb(j, tmport); 3342 tmport += 0x03; 3343 outb(satn[8], tmport); 3344 tmport += 0x07; 3345 3346 while ((inb(tmport) & 0x80) == 0x00) 3347 cpu_relax(); 3348 tmport -= 0x08; 3349 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { 3350 continue; 3351 } 3352 while (inb(tmport) != 0x8e) 3353 cpu_relax(); 3354 dev->active_id[c] |= m; 3355 3356 tmport = wkport + 0x10; 3357 outb(0x30, tmport); 3358 tmport = wkport + 0x14; 3359 outb(0x00, tmport); 3360 3361 phase_cmd: 3362 tmport = wkport + 0x18; 3363 outb(0x08, tmport); 3364 tmport += 0x07; 3365 while ((inb(tmport) & 0x80) == 0x00) 3366 cpu_relax(); 3367 tmport -= 0x08; 3368 j = inb(tmport); 3369 if (j != 0x16) { 3370 tmport = wkport + 0x10; 3371 outb(0x41, tmport); 3372 goto phase_cmd; 3373 } 3374 sel_ok: 3375 tmport = wkport + 0x03; 3376 outb(inqd[0], tmport++); 3377 outb(inqd[1], tmport++); 3378 outb(inqd[2], tmport++); 3379 outb(inqd[3], tmport++); 3380 outb(inqd[4], tmport++); 3381 outb(inqd[5], tmport); 3382 tmport += 0x07; 3383 outb(0, tmport); 3384 tmport += 0x02; 3385 outb(dev->id[c][i].devsp, tmport++); 3386 outb(0, tmport++); 3387 outb(inqd[6], tmport++); 3388 outb(inqd[7], tmport++); 3389 tmport += 0x03; 3390 outb(inqd[8], tmport); 3391 tmport += 0x07; 3392 while ((inb(tmport) & 0x80) == 0x00) 3393 cpu_relax(); 3394 tmport -= 0x08; 3395 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { 3396 continue; 3397 } 3398 while (inb(tmport) != 0x8e) 3399 cpu_relax(); 3400 tmport = wkport + 0x1b; 3401 outb(0x00, tmport); 3402 tmport = wkport + 0x18; 3403 outb(0x08, tmport); 3404 tmport += 0x07; 3405 j = 0; 3406 rd_inq_data: 3407 k = inb(tmport); 3408 if ((k & 0x01) != 0) { 3409 tmport -= 0x06; 3410 mbuf[j++] = inb(tmport); 3411 tmport += 0x06; 3412 goto rd_inq_data; 3413 } 3414 if ((k & 0x80) == 0) { 3415 goto rd_inq_data; 3416 } 3417 tmport -= 0x08; 3418 j = inb(tmport); 3419 if (j == 0x16) { 3420 goto inq_ok; 3421 } 3422 tmport = wkport + 0x10; 3423 outb(0x46, tmport); 3424 tmport += 0x02; 3425 outb(0, tmport++); 3426 outb(0, tmport++); 3427 outb(0, tmport++); 3428 tmport += 0x03; 3429 outb(0x08, tmport); 3430 tmport += 0x07; 3431 while ((inb(tmport) & 0x80) == 0x00) 3432 cpu_relax(); 3433 tmport -= 0x08; 3434 if (inb(tmport) != 0x16) { 3435 goto sel_ok; 3436 } 3437 inq_ok: 3438 mbuf[36] = 0; 3439 printk( KERN_INFO" ID: %2d %s\n", i, &mbuf[8]); 3440 dev->id[c][i].devtype = mbuf[0]; 3441 rmb = mbuf[1]; 3442 n = mbuf[7]; 3443 if ((mbuf[7] & 0x60) == 0) { 3444 goto not_wide; 3445 } 3446 if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { 3447 goto not_wide; 3448 } 3449 if (lvdmode == 0) { 3450 goto chg_wide; 3451 } 3452 if (dev->sp[c][i] != 0x04) { // force u2 3453 goto chg_wide; 3454 } 3455 3456 tmport = wkport + 0x1b; 3457 outb(0x01, tmport); 3458 tmport = wkport + 0x03; 3459 outb(satn[0], tmport++); 3460 outb(satn[1], tmport++); 3461 outb(satn[2], tmport++); 3462 outb(satn[3], tmport++); 3463 outb(satn[4], tmport++); 3464 outb(satn[5], tmport++); 3465 tmport += 0x06; 3466 outb(0, tmport); 3467 tmport += 0x02; 3468 outb(dev->id[c][i].devsp, tmport++); 3469 outb(0, tmport++); 3470 outb(satn[6], tmport++); 3471 outb(satn[7], tmport++); 3472 tmport += 0x03; 3473 outb(satn[8], tmport); 3474 tmport += 0x07; 3475 3476 while ((inb(tmport) & 0x80) == 0x00) 3477 cpu_relax(); 3478 tmport -= 0x08; 3479 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { 3480 continue; 3481 } 3482 while (inb(tmport) != 0x8e) 3483 cpu_relax(); 3484 try_u3: 3485 j = 0; 3486 tmport = wkport + 0x14; 3487 outb(0x09, tmport); 3488 tmport += 0x04; 3489 outb(0x20, tmport); 3490 tmport += 0x07; 3491 3492 while ((inb(tmport) & 0x80) == 0) { 3493 if ((inb(tmport) & 0x01) != 0) { 3494 tmport -= 0x06; 3495 outb(u3[j++], tmport); 3496 tmport += 0x06; 3497 } 3498 cpu_relax(); 3499 } 3500 tmport -= 0x08; 3501 while ((inb(tmport) & 0x80) == 0x00) 3502 cpu_relax(); 3503 j = inb(tmport) & 0x0f; 3504 if (j == 0x0f) { 3505 goto u3p_in; 3506 } 3507 if (j == 0x0a) { 3508 goto u3p_cmd; 3509 } 3510 if (j == 0x0e) { 3511 goto try_u3; 3512 } 3513 continue; 3514 u3p_out: 3515 tmport = wkport + 0x18; 3516 outb(0x20, tmport); 3517 tmport += 0x07; 3518 while ((inb(tmport) & 0x80) == 0) { 3519 if ((inb(tmport) & 0x01) != 0) { 3520 tmport -= 0x06; 3521 outb(0, tmport); 3522 tmport += 0x06; 3523 } 3524 cpu_relax(); 3525 } 3526 tmport -= 0x08; 3527 j = inb(tmport) & 0x0f; 3528 if (j == 0x0f) { 3529 goto u3p_in; 3530 } 3531 if (j == 0x0a) { 3532 goto u3p_cmd; 3533 } 3534 if (j == 0x0e) { 3535 goto u3p_out; 3536 } 3537 continue; 3538 u3p_in: 3539 tmport = wkport + 0x14; 3540 outb(0x09, tmport); 3541 tmport += 0x04; 3542 outb(0x20, tmport); 3543 tmport += 0x07; 3544 k = 0; 3545 u3p_in1: 3546 j = inb(tmport); 3547 if ((j & 0x01) != 0) { 3548 tmport -= 0x06; 3549 mbuf[k++] = inb(tmport); 3550 tmport += 0x06; 3551 goto u3p_in1; 3552 } 3553 if ((j & 0x80) == 0x00) { 3554 goto u3p_in1; 3555 } 3556 tmport -= 0x08; 3557 j = inb(tmport) & 0x0f; 3558 if (j == 0x0f) { 3559 goto u3p_in; 3560 } 3561 if (j == 0x0a) { 3562 goto u3p_cmd; 3563 } 3564 if (j == 0x0e) { 3565 goto u3p_out; 3566 } 3567 continue; 3568 u3p_cmd: 3569 tmport = wkport + 0x10; 3570 outb(0x30, tmport); 3571 tmport = wkport + 0x14; 3572 outb(0x00, tmport); 3573 tmport += 0x04; 3574 outb(0x08, tmport); 3575 tmport += 0x07; 3576 while ((inb(tmport) & 0x80) == 0x00); 3577 tmport -= 0x08; 3578 j = inb(tmport); 3579 if (j != 0x16) { 3580 if (j == 0x4e) { 3581 goto u3p_out; 3582 } 3583 continue; 3584 } 3585 if (mbuf[0] != 0x01) { 3586 goto chg_wide; 3587 } 3588 if (mbuf[1] != 0x06) { 3589 goto chg_wide; 3590 } 3591 if (mbuf[2] != 0x04) { 3592 goto chg_wide; 3593 } 3594 if (mbuf[3] == 0x09) { 3595 m = 1; 3596 m = m << i; 3597 dev->wide_id[c] |= m; 3598 dev->id[c][i].devsp = 0xce; 3599 #ifdef ED_DBGP 3600 printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); 3601 #endif 3602 continue; 3603 } 3604 chg_wide: 3605 tmport = wkport + 0x1b; 3606 outb(0x01, tmport); 3607 tmport = wkport + 0x03; 3608 outb(satn[0], tmport++); 3609 outb(satn[1], tmport++); 3610 outb(satn[2], tmport++); 3611 outb(satn[3], tmport++); 3612 outb(satn[4], tmport++); 3613 outb(satn[5], tmport++); 3614 tmport += 0x06; 3615 outb(0, tmport); 3616 tmport += 0x02; 3617 outb(dev->id[c][i].devsp, tmport++); 3618 outb(0, tmport++); 3619 outb(satn[6], tmport++); 3620 outb(satn[7], tmport++); 3621 tmport += 0x03; 3622 outb(satn[8], tmport); 3623 tmport += 0x07; 3624 3625 while ((inb(tmport) & 0x80) == 0x00) 3626 cpu_relax(); 3627 tmport -= 0x08; 3628 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { 3629 continue; 3630 } 3631 while (inb(tmport) != 0x8e) 3632 cpu_relax(); 3633 try_wide: 3634 j = 0; 3635 tmport = wkport + 0x14; 3636 outb(0x05, tmport); 3637 tmport += 0x04; 3638 outb(0x20, tmport); 3639 tmport += 0x07; 3640 3641 while ((inb(tmport) & 0x80) == 0) { 3642 if ((inb(tmport) & 0x01) != 0) { 3643 tmport -= 0x06; 3644 outb(wide[j++], tmport); 3645 tmport += 0x06; 3646 } 3647 cpu_relax(); 3648 } 3649 tmport -= 0x08; 3650 while ((inb(tmport) & 0x80) == 0x00) 3651 cpu_relax(); 3652 j = inb(tmport) & 0x0f; 3653 if (j == 0x0f) { 3654 goto widep_in; 3655 } 3656 if (j == 0x0a) { 3657 goto widep_cmd; 3658 } 3659 if (j == 0x0e) { 3660 goto try_wide; 3661 } 3662 continue; 3663 widep_out: 3664 tmport = wkport + 0x18; 3665 outb(0x20, tmport); 3666 tmport += 0x07; 3667 while ((inb(tmport) & 0x80) == 0) { 3668 if ((inb(tmport) & 0x01) != 0) { 3669 tmport -= 0x06; 3670 outb(0, tmport); 3671 tmport += 0x06; 3672 } 3673 cpu_relax(); 3674 } 3675 tmport -= 0x08; 3676 j = inb(tmport) & 0x0f; 3677 if (j == 0x0f) { 3678 goto widep_in; 3679 } 3680 if (j == 0x0a) { 3681 goto widep_cmd; 3682 } 3683 if (j == 0x0e) { 3684 goto widep_out; 3685 } 3686 continue; 3687 widep_in: 3688 tmport = wkport + 0x14; 3689 outb(0xff, tmport); 3690 tmport += 0x04; 3691 outb(0x20, tmport); 3692 tmport += 0x07; 3693 k = 0; 3694 widep_in1: 3695 j = inb(tmport); 3696 if ((j & 0x01) != 0) { 3697 tmport -= 0x06; 3698 mbuf[k++] = inb(tmport); 3699 tmport += 0x06; 3700 goto widep_in1; 3701 } 3702 if ((j & 0x80) == 0x00) { 3703 goto widep_in1; 3704 } 3705 tmport -= 0x08; 3706 j = inb(tmport) & 0x0f; 3707 if (j == 0x0f) { 3708 goto widep_in; 3709 } 3710 if (j == 0x0a) { 3711 goto widep_cmd; 3712 } 3713 if (j == 0x0e) { 3714 goto widep_out; 3715 } 3716 continue; 3717 widep_cmd: 3718 tmport = wkport + 0x10; 3719 outb(0x30, tmport); 3720 tmport = wkport + 0x14; 3721 outb(0x00, tmport); 3722 tmport += 0x04; 3723 outb(0x08, tmport); 3724 tmport += 0x07; 3725 while ((inb(tmport) & 0x80) == 0x00) 3726 cpu_relax(); 3727 tmport -= 0x08; 3728 j = inb(tmport); 3729 if (j != 0x16) { 3730 if (j == 0x4e) { 3731 goto widep_out; 3732 } 3733 continue; 3734 } 3735 if (mbuf[0] != 0x01) { 3736 goto not_wide; 3737 } 3738 if (mbuf[1] != 0x02) { 3739 goto not_wide; 3740 } 3741 if (mbuf[2] != 0x03) { 3742 goto not_wide; 3743 } 3744 if (mbuf[3] != 0x01) { 3745 goto not_wide; 3746 } 3747 m = 1; 3748 m = m << i; 3749 dev->wide_id[c] |= m; 3750 not_wide: 3751 if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || 3752 ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { 3753 m = 1; 3754 m = m << i; 3755 if ((dev->async[c] & m) != 0) { 3756 goto set_sync; 3757 } 3758 } 3759 continue; 3760 set_sync: 3761 if (dev->sp[c][i] == 0x02) { 3762 synu[4]=0x0c; 3763 synuw[4]=0x0c; 3764 } else { 3765 if (dev->sp[c][i] >= 0x03) { 3766 synu[4]=0x0a; 3767 synuw[4]=0x0a; 3768 } 3769 } 3770 tmport = wkport + 0x1b; 3771 j = 0; 3772 if ((m & dev->wide_id[c]) != 0) { 3773 j |= 0x01; 3774 } 3775 outb(j, tmport); 3776 tmport = wkport + 0x03; 3777 outb(satn[0], tmport++); 3778 outb(satn[1], tmport++); 3779 outb(satn[2], tmport++); 3780 outb(satn[3], tmport++); 3781 outb(satn[4], tmport++); 3782 outb(satn[5], tmport++); 3783 tmport += 0x06; 3784 outb(0, tmport); 3785 tmport += 0x02; 3786 outb(dev->id[c][i].devsp, tmport++); 3787 outb(0, tmport++); 3788 outb(satn[6], tmport++); 3789 outb(satn[7], tmport++); 3790 tmport += 0x03; 3791 outb(satn[8], tmport); 3792 tmport += 0x07; 3793 3794 while ((inb(tmport) & 0x80) == 0x00) 3795 cpu_relax(); 3796 tmport -= 0x08; 3797 if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { 3798 continue; 3799 } 3800 while (inb(tmport) != 0x8e) 3801 cpu_relax(); 3802 try_sync: 3803 j = 0; 3804 tmport = wkport + 0x14; 3805 outb(0x06, tmport); 3806 tmport += 0x04; 3807 outb(0x20, tmport); 3808 tmport += 0x07; 3809 3810 while ((inb(tmport) & 0x80) == 0) { 3811 if ((inb(tmport) & 0x01) != 0) { 3812 tmport -= 0x06; 3813 if ((m & dev->wide_id[c]) != 0) { 3814 if ((m & dev->ultra_map[c]) != 0) { 3815 outb(synuw[j++], tmport); 3816 } else { 3817 outb(synw[j++], tmport); 3818 } 3819 } else { 3820 if ((m & dev->ultra_map[c]) != 0) { 3821 outb(synu[j++], tmport); 3822 } else { 3823 outb(synn[j++], tmport); 3824 } 3825 } 3826 tmport += 0x06; 3827 } 3828 } 3829 tmport -= 0x08; 3830 while ((inb(tmport) & 0x80) == 0x00) 3831 cpu_relax(); 3832 j = inb(tmport) & 0x0f; 3833 if (j == 0x0f) { 3834 goto phase_ins; 3835 } 3836 if (j == 0x0a) { 3837 goto phase_cmds; 3838 } 3839 if (j == 0x0e) { 3840 goto try_sync; 3841 } 3842 continue; 3843 phase_outs: 3844 tmport = wkport + 0x18; 3845 outb(0x20, tmport); 3846 tmport += 0x07; 3847 while ((inb(tmport) & 0x80) == 0x00) { 3848 if ((inb(tmport) & 0x01) != 0x00) { 3849 tmport -= 0x06; 3850 outb(0x00, tmport); 3851 tmport += 0x06; 3852 } 3853 cpu_relax(); 3854 } 3855 tmport -= 0x08; 3856 j = inb(tmport); 3857 if (j == 0x85) { 3858 goto tar_dcons; 3859 } 3860 j &= 0x0f; 3861 if (j == 0x0f) { 3862 goto phase_ins; 3863 } 3864 if (j == 0x0a) { 3865 goto phase_cmds; 3866 } 3867 if (j == 0x0e) { 3868 goto phase_outs; 3869 } 3870 continue; 3871 phase_ins: 3872 tmport = wkport + 0x14; 3873 outb(0x06, tmport); 3874 tmport += 0x04; 3875 outb(0x20, tmport); 3876 tmport += 0x07; 3877 k = 0; 3878 phase_ins1: 3879 j = inb(tmport); 3880 if ((j & 0x01) != 0x00) { 3881 tmport -= 0x06; 3882 mbuf[k++] = inb(tmport); 3883 tmport += 0x06; 3884 goto phase_ins1; 3885 } 3886 if ((j & 0x80) == 0x00) { 3887 goto phase_ins1; 3888 } 3889 tmport -= 0x08; 3890 while ((inb(tmport) & 0x80) == 0x00); 3891 j = inb(tmport); 3892 if (j == 0x85) { 3893 goto tar_dcons; 3894 } 3895 j &= 0x0f; 3896 if (j == 0x0f) { 3897 goto phase_ins; 3898 } 3899 if (j == 0x0a) { 3900 goto phase_cmds; 3901 } 3902 if (j == 0x0e) { 3903 goto phase_outs; 3904 } 3905 continue; 3906 phase_cmds: 3907 tmport = wkport + 0x10; 3908 outb(0x30, tmport); 3909 tar_dcons: 3910 tmport = wkport + 0x14; 3911 outb(0x00, tmport); 3912 tmport += 0x04; 3913 outb(0x08, tmport); 3914 tmport += 0x07; 3915 while ((inb(tmport) & 0x80) == 0x00) 3916 cpu_relax(); 3917 tmport -= 0x08; 3918 j = inb(tmport); 3919 if (j != 0x16) { 3920 continue; 3921 } 3922 if (mbuf[0] != 0x01) { 3923 continue; 3924 } 3925 if (mbuf[1] != 0x03) { 3926 continue; 3927 } 3928 if (mbuf[4] == 0x00) { 3929 continue; 3930 } 3931 if (mbuf[3] > 0x64) { 3932 continue; 3933 } 3934 if (mbuf[4] > 0x0e) { 3935 mbuf[4] = 0x0e; 3936 } 3937 dev->id[c][i].devsp = mbuf[4]; 3938 if (mbuf[3] < 0x0c){ 3939 j = 0xb0; 3940 goto set_syn_ok; 3941 } 3942 if ((mbuf[3] < 0x0d) && (rmb == 0)) { 3943 j = 0xa0; 3944 goto set_syn_ok; 3945 } 3946 if (mbuf[3] < 0x1a) { 3947 j = 0x20; 3948 goto set_syn_ok; 3949 } 3950 if (mbuf[3] < 0x33) { 3951 j = 0x40; 3952 goto set_syn_ok; 3953 } 3954 if (mbuf[3] < 0x4c) { 3955 j = 0x50; 3956 goto set_syn_ok; 3957 } 3958 j = 0x60; 3959 set_syn_ok: 3960 dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; 3961 #ifdef ED_DBGP 3962 printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); 3963 #endif 3964 } 3965 tmport = wkport + 0x16; 3966 outb(0x80, tmport); 3967 } 3968 3969 module_init(atp870u_init); 3970 module_exit(atp870u_exit); 3971 3972