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