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