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