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