atp870u.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:59k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $
  2.  *  linux/kernel/atp870u.c
  3.  *
  4.  *  Copyright (C) 1997 Wu Ching Chen
  5.  *  2.1.x update (C) 1998  Krzysztof G. Baranowski
  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 (7.1)
  15.  */
  16. #include <linux/module.h>
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <linux/string.h>
  20. #include <linux/ioport.h>
  21. #include <linux/delay.h>
  22. #include <linux/sched.h>
  23. #include <linux/proc_fs.h>
  24. #include <linux/spinlock.h>
  25. #include <asm/system.h>
  26. #include <asm/io.h>
  27. #include <linux/pci.h>
  28. #include <linux/blk.h>
  29. #include "scsi.h"
  30. #include "hosts.h"
  31. #include "atp870u.h"
  32. #include<linux/stat.h>
  33. void mydlyu(unsigned int);
  34. /*
  35.  *   static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $";
  36.  */
  37. static unsigned char admaxu = 1;
  38. static unsigned short int sync_idu;
  39. static unsigned int irqnumu[2] = {0, 0};
  40. struct atp_unit
  41. {
  42. unsigned long ioport;
  43. unsigned long irq;
  44. unsigned long pciport;
  45. unsigned char last_cmd;
  46. unsigned char in_snd;
  47. unsigned char in_int;
  48. unsigned char quhdu;
  49. unsigned char quendu;
  50. unsigned char scam_on;
  51. unsigned char global_map;
  52. unsigned char chip_veru;
  53. unsigned char host_idu;
  54. int working;
  55. unsigned short wide_idu;
  56. unsigned short active_idu;
  57. unsigned short ultra_map;
  58. unsigned short async;
  59. unsigned short deviceid;
  60. unsigned char ata_cdbu[16];
  61. unsigned char sp[16];
  62. Scsi_Cmnd *querequ[qcnt];
  63. struct atp_id
  64. {
  65. unsigned char dirctu;
  66. unsigned char devspu;
  67. unsigned char devtypeu;
  68. unsigned long prdaddru;
  69. unsigned long tran_lenu;
  70. unsigned long last_lenu;
  71. unsigned char *prd_posu;
  72. unsigned char *prd_tableu;
  73. Scsi_Cmnd *curr_req;
  74. } id[16];
  75. };
  76. static struct Scsi_Host *atp_host[2] = {NULL, NULL};
  77. static struct atp_unit atp_unit[2];
  78. static void atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
  79. {
  80. unsigned long flags;
  81. unsigned short int tmpcip, id;
  82. unsigned char i, j, h, target_id, lun;
  83. unsigned char *prd;
  84. Scsi_Cmnd *workrequ;
  85. unsigned int workportu, tmport;
  86. unsigned long adrcntu, k;
  87. int errstus;
  88. struct atp_unit *dev = dev_id;
  89. for (h = 0; h < 2; h++) {
  90. if (irq == irqnumu[h]) {
  91. goto irq_numok;
  92. }
  93. }
  94. return;
  95. irq_numok:
  96. dev->in_int = 1;
  97. workportu = dev->ioport;
  98. tmport = workportu;
  99. if (dev->working != 0)
  100. {
  101. tmport += 0x1f;
  102. j = inb(tmport);
  103. if ((j & 0x80) == 0)
  104. {
  105. dev->in_int = 0;
  106. return;
  107. }
  108. tmpcip = dev->pciport;
  109. if ((inb(tmpcip) & 0x08) != 0)
  110. {
  111. tmpcip += 0x2;
  112. for (k=0; k < 1000; k++)
  113. {
  114. if ((inb(tmpcip) & 0x08) == 0)
  115. {
  116. goto stop_dma;
  117. }
  118. if ((inb(tmpcip) & 0x01) == 0)
  119. {
  120. goto stop_dma;
  121. }
  122. }
  123. }
  124. stop_dma:
  125. tmpcip = dev->pciport;
  126. outb(0x00, tmpcip);
  127. tmport -= 0x08;
  128. i = inb(tmport);
  129. tmport -= 0x02;
  130. target_id = inb(tmport);
  131. tmport += 0x02;
  132. /*
  133.  * Remap wide devices onto id numbers
  134.  */
  135. if ((target_id & 0x40) != 0) {
  136. target_id = (target_id & 0x07) | 0x08;
  137. } else {
  138. target_id &= 0x07;
  139. }
  140. if ((j & 0x40) != 0)
  141. {
  142.      if (dev->last_cmd == 0xff)
  143.      {
  144. dev->last_cmd = target_id;
  145.      }
  146.      dev->last_cmd |= 0x40;
  147. }
  148. if (i == 0x85)
  149. {
  150. if ((dev->last_cmd & 0xf0) != 0x40)
  151. {
  152.    dev->last_cmd = 0xff;
  153. }
  154. /*
  155.  * Flip wide
  156.  */
  157. if (dev->wide_idu != 0)
  158. {
  159. tmport = workportu + 0x1b;
  160. outb(0x01,tmport);
  161. while ((inb(tmport) & 0x01) != 0x01)
  162. {
  163.    outb(0x01,tmport);
  164. }
  165. }
  166. /*
  167.  * Issue more commands
  168.  */
  169. if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) &&
  170.     (dev->in_snd == 0))
  171. {
  172. send_s870(h);
  173. }
  174. /*
  175.  * Done
  176.  */
  177. dev->in_int = 0;
  178. return;
  179. }
  180. if (i == 0x40)
  181. {
  182.      dev->last_cmd |= 0x40;
  183.      dev->in_int = 0;
  184.      return;
  185. }
  186. if (i == 0x21)
  187. {
  188. if ((dev->last_cmd & 0xf0) != 0x40)
  189. {
  190.    dev->last_cmd = 0xff;
  191. }
  192. tmport -= 0x05;
  193. adrcntu = 0;
  194. ((unsigned char *) &adrcntu)[2] = inb(tmport++);
  195. ((unsigned char *) &adrcntu)[1] = inb(tmport++);
  196. ((unsigned char *) &adrcntu)[0] = inb(tmport);
  197. k = dev->id[target_id].last_lenu;
  198. k -= adrcntu;
  199. dev->id[target_id].tran_lenu = k;
  200. dev->id[target_id].last_lenu = adrcntu;
  201. tmport -= 0x04;
  202. outb(0x41, tmport);
  203. tmport += 0x08;
  204. outb(0x08, tmport);
  205. dev->in_int = 0;
  206. return;
  207. }
  208. if ((i == 0x80) || (i == 0x8f))
  209. {
  210. lun = 0;
  211. tmport -= 0x07;
  212. j = inb(tmport);
  213. if (j == 0x44 || i==0x80) {
  214. tmport += 0x0d;
  215. lun = inb(tmport) & 0x07;
  216. } else {
  217. if ((dev->last_cmd & 0xf0) != 0x40)
  218. {
  219.    dev->last_cmd = 0xff;
  220. }
  221. if (j == 0x41)
  222. {
  223. tmport += 0x02;
  224. adrcntu = 0;
  225. ((unsigned char *) &adrcntu)[2] = inb(tmport++);
  226. ((unsigned char *) &adrcntu)[1] = inb(tmport++);
  227. ((unsigned char *) &adrcntu)[0] = inb(tmport);
  228. k = dev->id[target_id].last_lenu;
  229. k -= adrcntu;
  230. dev->id[target_id].tran_lenu = k;
  231. dev->id[target_id].last_lenu = adrcntu;
  232. tmport += 0x04;
  233. outb(0x08, tmport);
  234. dev->in_int = 0;
  235. return;
  236. }
  237. else
  238. {
  239. outb(0x46, tmport);
  240. dev->id[target_id].dirctu = 0x00;
  241. tmport += 0x02;
  242. outb(0x00, tmport++);
  243. outb(0x00, tmport++);
  244. outb(0x00, tmport++);
  245. tmport += 0x03;
  246. outb(0x08, tmport);
  247. dev->in_int = 0;
  248. return;
  249. }
  250. }
  251. if (dev->last_cmd != 0xff)
  252. {
  253.    dev->last_cmd |= 0x40;
  254. }
  255. tmport = workportu + 0x10;
  256. outb(0x45, tmport);
  257. tmport += 0x06;
  258. target_id = inb(tmport);
  259. /*
  260.  * Remap wide identifiers
  261.  */
  262. if ((target_id & 0x10) != 0)
  263. {
  264. target_id = (target_id & 0x07) | 0x08;
  265. } else {
  266. target_id &= 0x07;
  267. }
  268. workrequ = dev->id[target_id].curr_req;
  269. tmport = workportu + 0x0f;
  270. outb(lun, tmport);
  271. tmport += 0x02;
  272. outb(dev->id[target_id].devspu, tmport++);
  273. adrcntu = dev->id[target_id].tran_lenu;
  274. k = dev->id[target_id].last_lenu;
  275. outb(((unsigned char *) &k)[2], tmport++);
  276. outb(((unsigned char *) &k)[1], tmport++);
  277. outb(((unsigned char *) &k)[0], tmport++);
  278. /* Remap wide */
  279. j = target_id;
  280. if (target_id > 7) {
  281. j = (j & 0x07) | 0x40;
  282. }
  283. /* Add direction */
  284. j |= dev->id[target_id].dirctu;
  285. outb(j, tmport++);
  286. outb(0x80, tmport);
  287. /* enable 32 bit fifo transfer */
  288. if (dev->deviceid != 0x8081)
  289. {
  290.    tmport = workportu + 0x3a;
  291.    if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
  292.        (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
  293.    {
  294.       outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
  295.    }
  296.    else
  297.    {
  298.       outb((unsigned char)(inb(tmport) & 0xf3),tmport);
  299.    }
  300. }
  301. else
  302. {
  303.    tmport = workportu - 0x05;
  304.    if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
  305.        (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
  306.    {
  307.       outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
  308.    }
  309.    else
  310.    {
  311.       outb((unsigned char)(inb(tmport) & 0x3f),tmport);
  312.    }
  313. }
  314. tmport = workportu + 0x1b;
  315. j = 0;
  316. id = 1;
  317. id = id << target_id;
  318. /*
  319.  * Is this a wide device
  320.  */
  321. if ((id & dev->wide_idu) != 0) {
  322. j |= 0x01;
  323. }
  324. outb(j, tmport);
  325. while ((inb(tmport) & 0x01) != j)
  326. {
  327.    outb(j,tmport);
  328. }
  329. if (dev->id[target_id].last_lenu == 0) {
  330. tmport = workportu + 0x18;
  331. outb(0x08, tmport);
  332. dev->in_int = 0;
  333. return;
  334. }
  335. prd = dev->id[target_id].prd_posu;
  336. while (adrcntu != 0)
  337. {
  338. id = ((unsigned short int *) (prd))[2];
  339. if (id == 0) {
  340. k = 0x10000;
  341. } else {
  342. k = id;
  343. }
  344. if (k > adrcntu) {
  345. ((unsigned short int *) (prd))[2] = (unsigned short int)
  346.     (k - adrcntu);
  347. ((unsigned long *) (prd))[0] += adrcntu;
  348. adrcntu = 0;
  349. dev->id[target_id].prd_posu = prd;
  350. } else {
  351. adrcntu -= k;
  352. dev->id[target_id].prdaddru += 0x08;
  353. prd += 0x08;
  354. if (adrcntu == 0) {
  355. dev->id[target_id].prd_posu = prd;
  356. }
  357. }
  358. }
  359. tmpcip = dev->pciport + 0x04;
  360. outl(dev->id[target_id].prdaddru, tmpcip);
  361. tmpcip -= 0x02;
  362. outb(0x06, tmpcip);
  363. outb(0x00, tmpcip);
  364. tmpcip -= 0x02;
  365. tmport = workportu + 0x18;
  366. /*
  367.  * Check transfer direction
  368.  */
  369. if (dev->id[target_id].dirctu != 0) {
  370. outb(0x08, tmport);
  371. outb(0x01, tmpcip);
  372. dev->in_int = 0;
  373. return;
  374. }
  375. outb(0x08, tmport);
  376. outb(0x09, tmpcip);
  377. dev->in_int = 0;
  378. return;
  379. }
  380. /*
  381.  * Current scsi request on this target
  382.  */
  383. workrequ = dev->id[target_id].curr_req;
  384. if (i == 0x42) {
  385. if ((dev->last_cmd & 0xf0) != 0x40)
  386. {
  387.    dev->last_cmd = 0xff;
  388. }
  389. errstus = 0x02;
  390. workrequ->result = errstus;
  391. goto go_42;
  392. }
  393. if (i == 0x16)
  394. {
  395. if ((dev->last_cmd & 0xf0) != 0x40)
  396. {
  397.    dev->last_cmd = 0xff;
  398. }
  399. errstus = 0;
  400. tmport -= 0x08;
  401. errstus = inb(tmport);
  402. workrequ->result = errstus;
  403. go_42:
  404. /*
  405.  * Complete the command
  406.  */
  407. spin_lock_irqsave(&io_request_lock, flags);
  408. (*workrequ->scsi_done) (workrequ);
  409. /*
  410.  * Clear it off the queue
  411.  */
  412. dev->id[target_id].curr_req = 0;
  413. dev->working--;
  414. spin_unlock_irqrestore(&io_request_lock, flags);
  415. /*
  416.  * Take it back wide
  417.  */
  418. if (dev->wide_idu != 0) {
  419. tmport = workportu + 0x1b;
  420. outb(0x01,tmport);
  421. while ((inb(tmport) & 0x01) != 0x01)
  422. {
  423.    outb(0x01,tmport);
  424. }
  425. }
  426. /*
  427.  * If there is stuff to send and nothing going then send it
  428.  */
  429. if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) &&
  430.     (dev->in_snd == 0))
  431. {
  432.    send_s870(h);
  433. }
  434. dev->in_int = 0;
  435. return;
  436. }
  437. if ((dev->last_cmd & 0xf0) != 0x40)
  438. {
  439.    dev->last_cmd = 0xff;
  440. }
  441. if (i == 0x4f) {
  442. i = 0x89;
  443. }
  444. i &= 0x0f;
  445. if (i == 0x09) {
  446. tmpcip = tmpcip + 4;
  447. outl(dev->id[target_id].prdaddru, tmpcip);
  448. tmpcip = tmpcip - 2;
  449. outb(0x06, tmpcip);
  450. outb(0x00, tmpcip);
  451. tmpcip = tmpcip - 2;
  452. tmport = workportu + 0x10;
  453. outb(0x41, tmport);
  454. dev->id[target_id].dirctu = 0x00;
  455. tmport += 0x08;
  456. outb(0x08, tmport);
  457. outb(0x09, tmpcip);
  458. dev->in_int = 0;
  459. return;
  460. }
  461. if (i == 0x08) {
  462. tmpcip = tmpcip + 4;
  463. outl(dev->id[target_id].prdaddru, tmpcip);
  464. tmpcip = tmpcip - 2;
  465. outb(0x06, tmpcip);
  466. outb(0x00, tmpcip);
  467. tmpcip = tmpcip - 2;
  468. tmport = workportu + 0x10;
  469. outb(0x41, tmport);
  470. tmport += 0x05;
  471. outb((unsigned char) (inb(tmport) | 0x20), tmport);
  472. dev->id[target_id].dirctu = 0x20;
  473. tmport += 0x03;
  474. outb(0x08, tmport);
  475. outb(0x01, tmpcip);
  476. dev->in_int = 0;
  477. return;
  478. }
  479. tmport -= 0x07;
  480. if (i == 0x0a) {
  481. outb(0x30, tmport);
  482. } else {
  483. outb(0x46, tmport);
  484. }
  485. dev->id[target_id].dirctu = 0x00;
  486. tmport += 0x02;
  487. outb(0x00, tmport++);
  488. outb(0x00, tmport++);
  489. outb(0x00, tmport++);
  490. tmport += 0x03;
  491. outb(0x08, tmport);
  492. dev->in_int = 0;
  493. return;
  494. } else {
  495. // tmport = workportu + 0x17;
  496. // inb(tmport);
  497. // dev->working = 0;
  498. dev->in_int = 0;
  499. return;
  500. }
  501. }
  502. int atp870u_queuecommand(Scsi_Cmnd * req_p, void (*done) (Scsi_Cmnd *))
  503. {
  504. unsigned char h;
  505. unsigned long flags;
  506. unsigned short int m;
  507. unsigned int tmport;
  508. struct atp_unit *dev;
  509. for (h = 0; h <= admaxu; h++) {
  510. if (req_p->host == atp_host[h]) {
  511. goto host_ok;
  512. }
  513. }
  514. return 0;
  515. host_ok:
  516. if (req_p->channel != 0) {
  517. req_p->result = 0x00040000;
  518. done(req_p);
  519. return 0;
  520. }
  521. dev = &atp_unit[h];
  522. m = 1;
  523. m = m << req_p->target;
  524. /*
  525.  * Fake a timeout for missing targets
  526.  */
  527. if ((m & dev->active_idu) == 0) {
  528. req_p->result = 0x00040000;
  529. done(req_p);
  530. return 0;
  531. }
  532. if (done) {
  533. req_p->scsi_done = done;
  534. } else {
  535. printk(KERN_WARNING "atp870u_queuecommand: done can't be NULLn");
  536. req_p->result = 0;
  537. done(req_p);
  538. return 0;
  539. }
  540. /*
  541.  * Count new command
  542.  */
  543. save_flags(flags);
  544. cli();
  545. dev->quendu++;
  546. if (dev->quendu >= qcnt) {
  547. dev->quendu = 0;
  548. }
  549. /*
  550.  * Check queue state
  551.  */
  552. if (dev->quhdu == dev->quendu) {
  553. if (dev->quendu == 0) {
  554. dev->quendu = qcnt;
  555. }
  556. dev->quendu--;
  557. req_p->result = 0x00020000;
  558. done(req_p);
  559. restore_flags(flags);
  560. return 0;
  561. }
  562. dev->querequ[dev->quendu] = req_p;
  563. tmport = dev->ioport + 0x1c;
  564. restore_flags(flags);
  565. if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) {
  566. send_s870(h);
  567. }
  568. return 0;
  569. }
  570. void mydlyu(unsigned int dlycnt)
  571. {
  572. unsigned int i;
  573. for (i = 0; i < dlycnt; i++) {
  574. inb(0x80);
  575. }
  576. }
  577. void send_s870(unsigned char h)
  578. {
  579. unsigned int tmport;
  580. Scsi_Cmnd *workrequ;
  581. unsigned long flags;
  582. unsigned int i;
  583. unsigned char j, target_id;
  584. unsigned char *prd;
  585. unsigned short int tmpcip, w;
  586. unsigned long l, bttl;
  587. unsigned int workportu;
  588. struct scatterlist *sgpnt;
  589. struct atp_unit *dev = &atp_unit[h];
  590. save_flags(flags);
  591. cli();
  592. if (dev->in_snd != 0) {
  593. restore_flags(flags);
  594. return;
  595. }
  596. dev->in_snd = 1;
  597. if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) {
  598. dev->last_cmd &= 0x0f;
  599. workrequ = dev->id[dev->last_cmd].curr_req;
  600. if (workrequ != NULL)      /* check NULL pointer */
  601. {
  602.    goto cmd_subp;
  603. }
  604. dev->last_cmd = 0xff;
  605. if (dev->quhdu == dev->quendu)
  606. {
  607.    dev->in_snd = 0;
  608.    restore_flags(flags);
  609.    return ;
  610. }
  611. }
  612. if ((dev->last_cmd != 0xff) && (dev->working != 0))
  613. {
  614.      dev->in_snd = 0;
  615.      restore_flags(flags);
  616.      return ;
  617. }
  618. dev->working++;
  619. j = dev->quhdu;
  620. dev->quhdu++;
  621. if (dev->quhdu >= qcnt) {
  622. dev->quhdu = 0;
  623. }
  624. workrequ = dev->querequ[dev->quhdu];
  625. if (dev->id[workrequ->target].curr_req == 0) {
  626. dev->id[workrequ->target].curr_req = workrequ;
  627. dev->last_cmd = workrequ->target;
  628. goto cmd_subp;
  629. }
  630. dev->quhdu = j;
  631. dev->working--;
  632. dev->in_snd = 0;
  633. restore_flags(flags);
  634. return;
  635. cmd_subp:
  636. workportu = dev->ioport;
  637. tmport = workportu + 0x1f;
  638. if ((inb(tmport) & 0xb0) != 0) {
  639. goto abortsnd;
  640. }
  641. tmport = workportu + 0x1c;
  642. if (inb(tmport) == 0) {
  643. goto oktosend;
  644. }
  645. abortsnd:
  646. dev->last_cmd |= 0x40;
  647. dev->in_snd = 0;
  648. restore_flags(flags);
  649. return;
  650. oktosend:
  651. memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len);
  652. if (dev->ata_cdbu[0] == READ_CAPACITY) {
  653. if (workrequ->request_bufflen > 8) {
  654. workrequ->request_bufflen = 0x08;
  655. }
  656. }
  657. if (dev->ata_cdbu[0] == 0x00) {
  658. workrequ->request_bufflen = 0;
  659. }
  660. tmport = workportu + 0x1b;
  661. j = 0;
  662. target_id = workrequ->target;
  663. /*
  664.  * Wide ?
  665.  */
  666. w = 1;
  667. w = w << target_id;
  668. if ((w & dev->wide_idu) != 0) {
  669. j |= 0x01;
  670. }
  671. outb(j, tmport);
  672. while ((inb(tmport) & 0x01) != j)
  673. {
  674.    outb(j,tmport);
  675. }
  676. /*
  677.  * Write the command
  678.  */
  679. tmport = workportu;
  680. outb(workrequ->cmd_len, tmport++);
  681. outb(0x2c, tmport++);
  682. outb(0xcf, tmport++);
  683. for (i = 0; i < workrequ->cmd_len; i++) {
  684. outb(dev->ata_cdbu[i], tmport++);
  685. }
  686. tmport = workportu + 0x0f;
  687. outb(workrequ->lun, tmport);
  688. tmport += 0x02;
  689. /*
  690.  * Write the target
  691.  */
  692. outb(dev->id[target_id].devspu, tmport++);
  693. /*
  694.  * Figure out the transfer size
  695.  */
  696. if (workrequ->use_sg)
  697. {
  698. l = 0;
  699. sgpnt = (struct scatterlist *) workrequ->request_buffer;
  700. for (i = 0; i < workrequ->use_sg; i++)
  701. {
  702. if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER)
  703. {
  704. panic("Foooooooood fight!");
  705. }
  706. l += sgpnt[i].length;
  707. }
  708. } else {
  709. l = workrequ->request_bufflen;
  710. }
  711. /*
  712.  * Write transfer size
  713.  */
  714. outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++);
  715. outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++);
  716. outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++);
  717. j = target_id;
  718. dev->id[j].last_lenu = l;
  719. dev->id[j].tran_lenu = 0;
  720. /*
  721.  * Flip the wide bits
  722.  */
  723. if ((j & 0x08) != 0) {
  724. j = (j & 0x07) | 0x40;
  725. }
  726. /*
  727.  * Check transfer direction
  728.  */
  729. if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
  730.     (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT)) {
  731. outb((unsigned char) (j | 0x20), tmport++);
  732. } else {
  733. outb(j, tmport++);
  734. }
  735. outb((unsigned char)(inb(tmport) | 0x80),tmport);
  736. outb(0x80, tmport);
  737. tmport = workportu + 0x1c;
  738. dev->id[target_id].dirctu = 0;
  739. if (l == 0) {
  740. if (inb(tmport) == 0) {
  741. tmport = workportu + 0x18;
  742. outb(0x08, tmport);
  743. } else {
  744. dev->last_cmd |= 0x40;
  745. }
  746. dev->in_snd = 0;
  747. restore_flags(flags);
  748. return;
  749. }
  750. tmpcip = dev->pciport;
  751. prd = dev->id[target_id].prd_tableu;
  752. dev->id[target_id].prd_posu = prd;
  753. /*
  754.  * Now write the request list. Either as scatter/gather or as
  755.  * a linear chain.
  756.  */
  757. if (workrequ->use_sg)
  758. {
  759. sgpnt = (struct scatterlist *) workrequ->request_buffer;
  760. i = 0;
  761. for (j = 0; j < workrequ->use_sg; j++) {
  762. (unsigned long) (((unsigned long *) (prd))[i >> 1]) = virt_to_bus(sgpnt[j].address);
  763. (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = sgpnt[j].length;
  764. (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0;
  765. i += 0x04;
  766. }
  767. (unsigned short int) (((unsigned short int *) (prd))[i - 1]) = 0x8000;
  768. } else {
  769. /*
  770.  * For a linear request write a chain of blocks
  771.  */
  772. bttl = virt_to_bus(workrequ->request_buffer);
  773. l = workrequ->request_bufflen;
  774. i = 0;
  775. while (l > 0x10000) {
  776. (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x0000;
  777. (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = 0x0000;
  778. (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
  779. l -= 0x10000;
  780. bttl += 0x10000;
  781. i += 0x04;
  782. }
  783. (unsigned short int) (((unsigned short int *) (prd))[i + 3]) = 0x8000;
  784. (unsigned short int) (((unsigned short int *) (prd))[i + 2]) = l;
  785. (unsigned long) (((unsigned long *) (prd))[i >> 1]) = bttl;
  786. }
  787. tmpcip = tmpcip + 4;
  788. dev->id[target_id].prdaddru = virt_to_bus(dev->id[target_id].prd_tableu);
  789. outl(dev->id[target_id].prdaddru, tmpcip);
  790. tmpcip = tmpcip - 2;
  791. outb(0x06, tmpcip);
  792. outb(0x00, tmpcip);
  793. tmpcip = tmpcip - 2;
  794. if (dev->deviceid != 0x8081)
  795. {
  796.    tmport = workportu + 0x3a;
  797.    if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
  798.        (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
  799.    {
  800.       outb((unsigned char)((inb(tmport) & 0xf3) | 0x08),tmport);
  801.    }
  802.    else
  803.    {
  804.       outb((unsigned char)(inb(tmport) & 0xf3),tmport);
  805.    }
  806. }
  807. else
  808. {
  809.    tmport = workportu - 0x05;
  810.    if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) ||
  811.        (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a))
  812.    {
  813.       outb((unsigned char)((inb(tmport) & 0x3f) | 0xc0),tmport);
  814.    }
  815.    else
  816.    {
  817.       outb((unsigned char)(inb(tmport) & 0x3f),tmport);
  818.    }
  819. }
  820. tmport = workportu + 0x1c;
  821. if ((dev->ata_cdbu[0] == WRITE_6) || (dev->ata_cdbu[0] == WRITE_10) ||
  822.     (dev->ata_cdbu[0] == WRITE_12) || (dev->ata_cdbu[0] == MODE_SELECT))
  823. {
  824. dev->id[target_id].dirctu = 0x20;
  825. if (inb(tmport) == 0) {
  826. tmport = workportu + 0x18;
  827. outb(0x08, tmport);
  828. outb(0x01, tmpcip);
  829. } else {
  830. dev->last_cmd |= 0x40;
  831. }
  832. dev->in_snd = 0;
  833. restore_flags(flags);
  834. return;
  835. }
  836. if (inb(tmport) == 0)
  837. {
  838. tmport = workportu + 0x18;
  839. outb(0x08, tmport);
  840. outb(0x09, tmpcip);
  841. } else {
  842. dev->last_cmd |= 0x40;
  843. }
  844. dev->in_snd = 0;
  845. restore_flags(flags);
  846. return;
  847. }
  848. static void internal_done(Scsi_Cmnd * SCpnt)
  849. {
  850. SCpnt->SCp.Status++;
  851. }
  852. int atp870u_command(Scsi_Cmnd * SCpnt)
  853. {
  854. atp870u_queuecommand(SCpnt, internal_done);
  855. SCpnt->SCp.Status = 0;
  856. while (!SCpnt->SCp.Status)
  857. barrier();
  858. return SCpnt->result;
  859. }
  860. unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
  861. {
  862. unsigned int tmport;
  863. unsigned short int i, k;
  864. unsigned char j;
  865. tmport = dev->ioport + 0x1c;
  866. outw(*val, tmport);
  867. FUN_D7:
  868. for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns)  */
  869. k = inw(tmport);
  870. j = (unsigned char) (k >> 8);
  871. if ((k & 0x8000) != 0) { /* DB7 all release?    */
  872. goto FUN_D7;
  873. }
  874. }
  875. *val |= 0x4000;  /* assert DB6 */
  876. outw(*val, tmport);
  877. *val &= 0xdfff;  /* assert DB5 */
  878. outw(*val, tmport);
  879. FUN_D5:
  880. for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */
  881. if ((inw(tmport) & 0x2000) != 0) { /* DB5 all release?   */
  882. goto FUN_D5;
  883. }
  884. }
  885. *val |= 0x8000;  /* no DB4-0, assert DB7    */
  886. *val &= 0xe0ff;
  887. outw(*val, tmport);
  888. *val &= 0xbfff;  /* release DB6    */
  889. outw(*val, tmport);
  890.       FUN_D6:
  891. for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns)  */
  892. if ((inw(tmport) & 0x4000) != 0) { /* DB6 all release?  */
  893. goto FUN_D6;
  894. }
  895. }
  896. return j;
  897. }
  898. void tscam(unsigned char host)
  899. {
  900. unsigned int tmport;
  901. unsigned char i, j, k;
  902. unsigned long n;
  903. unsigned short int m, assignid_map, val;
  904. unsigned char mbuf[33], quintet[2];
  905. struct atp_unit *dev = &atp_unit[host];
  906. static unsigned char g2q_tab[8] = {
  907. 0x38, 0x31, 0x32, 0x2b, 0x34, 0x2d, 0x2e, 0x27
  908. };
  909. for (i = 0; i < 0x10; i++) {
  910. mydlyu(0xffff);
  911. }
  912. tmport = dev->ioport + 1;
  913. outb(0x08, tmport++);
  914. outb(0x7f, tmport);
  915. tmport = dev->ioport + 0x11;
  916. outb(0x20, tmport);
  917. if ((dev->scam_on & 0x40) == 0) {
  918. return;
  919. }
  920. m = 1;
  921. m <<= dev->host_idu;
  922. j = 16;
  923. if (dev->chip_veru < 4) {
  924. m |= 0xff00;
  925. j = 8;
  926. }
  927. assignid_map = m;
  928. tmport = dev->ioport + 0x02;
  929. outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */
  930. outb(0, tmport++);
  931. outb(0, tmport++);
  932. outb(0, tmport++);
  933. outb(0, tmport++);
  934. outb(0, tmport++);
  935. outb(0, tmport++);
  936. for (i = 0; i < j; i++) {
  937. m = 1;
  938. m = m << i;
  939. if ((m & assignid_map) != 0) {
  940. continue;
  941. }
  942. tmport = dev->ioport + 0x0f;
  943. outb(0, tmport++);
  944. tmport += 0x02;
  945. outb(0, tmport++);
  946. outb(0, tmport++);
  947. outb(0, tmport++);
  948. if (i > 7) {
  949. k = (i & 0x07) | 0x40;
  950. } else {
  951. k = i;
  952. }
  953. outb(k, tmport++);
  954. tmport = dev->ioport + 0x1b;
  955. if (dev->chip_veru == 4) {
  956. outb(0x01, tmport);
  957. } else {
  958. outb(0x00, tmport);
  959. }
  960. wait_rdyok:
  961. tmport = dev->ioport + 0x18;
  962. outb(0x09, tmport);
  963. tmport += 0x07;
  964. while ((inb(tmport) & 0x80) == 0x00);
  965. tmport -= 0x08;
  966. k = inb(tmport);
  967. if (k != 0x16) {
  968. if ((k == 0x85) || (k == 0x42)) {
  969. continue;
  970. }
  971. tmport = dev->ioport + 0x10;
  972. outb(0x41, tmport);
  973. goto wait_rdyok;
  974. }
  975. assignid_map |= m;
  976. }
  977. tmport = dev->ioport + 0x02;
  978. outb(0x7f, tmport);
  979. tmport = dev->ioport + 0x1b;
  980. outb(0x02, tmport);
  981. outb(0, 0x80);
  982. val = 0x0080; /* bsy */
  983. tmport = dev->ioport + 0x1c;
  984. outw(val, tmport);
  985. val |= 0x0040; /* sel */
  986. outw(val, tmport);
  987. val |= 0x0004; /* msg */
  988. outw(val, tmport);
  989. inb(0x80); /* 2 deskew delay(45ns*2=90ns) */
  990. val &= 0x007f; /* no bsy  */
  991. outw(val, tmport);
  992. mydlyu(0xffff);  /* recommanded SCAM selection response time */
  993. mydlyu(0xffff);
  994. val &= 0x00fb; /* after 1ms no msg */
  995. outw(val, tmport);
  996. wait_nomsg:
  997. if ((inb(tmport) & 0x04) != 0) {
  998. goto wait_nomsg;
  999. }
  1000. outb(1, 0x80);
  1001. mydlyu(100);
  1002. for (n = 0; n < 0x30000; n++) {
  1003. if ((inb(tmport) & 0x80) != 0) { /* bsy ? */
  1004. goto wait_io;
  1005. }
  1006. }
  1007. goto TCM_SYNC;
  1008. wait_io:
  1009. for (n = 0; n < 0x30000; n++) {
  1010. if ((inb(tmport) & 0x81) == 0x0081) {
  1011. goto wait_io1;
  1012. }
  1013. }
  1014. goto TCM_SYNC;
  1015. wait_io1:
  1016. inb(0x80);
  1017. val |= 0x8003; /* io,cd,db7  */
  1018. outw(val, tmport);
  1019. inb(0x80);
  1020. val &= 0x00bf; /* no sel     */
  1021. outw(val, tmport);
  1022. outb(2, 0x80);
  1023. TCM_SYNC:
  1024. mydlyu(0x800);
  1025. if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */
  1026. outw(0, tmport--);
  1027. outb(0, tmport);
  1028. tmport = dev->ioport + 0x15;
  1029. outb(0, tmport);
  1030. tmport += 0x03;
  1031. outb(0x09, tmport);
  1032. tmport += 0x07;
  1033. while ((inb(tmport) & 0x80) == 0);
  1034. tmport -= 0x08;
  1035. inb(tmport);
  1036. return;
  1037. }
  1038. val &= 0x00ff; /* synchronization  */
  1039. val |= 0x3f00;
  1040. fun_scam(dev, &val);
  1041. outb(3, 0x80);
  1042. val &= 0x00ff; /* isolation     */
  1043. val |= 0x2000;
  1044. fun_scam(dev, &val);
  1045. outb(4, 0x80);
  1046. i = 8;
  1047. j = 0;
  1048. TCM_ID:
  1049. if ((inw(tmport) & 0x2000) == 0) {
  1050. goto TCM_ID;
  1051. }
  1052. outb(5, 0x80);
  1053. val &= 0x00ff; /* get ID_STRING */
  1054. val |= 0x2000;
  1055. k = fun_scam(dev, &val);
  1056. if ((k & 0x03) == 0) {
  1057. goto TCM_5;
  1058. }
  1059. mbuf[j] <<= 0x01;
  1060. mbuf[j] &= 0xfe;
  1061. if ((k & 0x02) != 0) {
  1062. mbuf[j] |= 0x01;
  1063. }
  1064. i--;
  1065. if (i > 0) {
  1066. goto TCM_ID;
  1067. }
  1068. j++;
  1069. i = 8;
  1070. goto TCM_ID;
  1071. TCM_5: /* isolation complete..  */
  1072. /*    mbuf[32]=0;
  1073. printk(" n%x %x %x %sn ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
  1074. i = 15;
  1075. j = mbuf[0];
  1076. if ((j & 0x20) != 0) { /* bit5=1:ID upto 7  */
  1077. i = 7;
  1078. }
  1079. if ((j & 0x06) == 0) { /* IDvalid? */
  1080. goto G2Q5;
  1081. }
  1082. k = mbuf[1];
  1083. small_id:
  1084. m = 1;
  1085. m <<= k;
  1086. if ((m & assignid_map) == 0) {
  1087. goto G2Q_QUIN;
  1088. }
  1089. if (k > 0) {
  1090. k--;
  1091. goto small_id;
  1092. }
  1093. G2Q5: /* srch from max acceptable ID#  */
  1094. k = i; /* max acceptable ID#  */
  1095. G2Q_LP:
  1096. m = 1;
  1097. m <<= k;
  1098. if ((m & assignid_map) == 0) {
  1099. goto G2Q_QUIN;
  1100. }
  1101. if (k > 0) {
  1102. k--;
  1103. goto G2Q_LP;
  1104. }
  1105. G2Q_QUIN: /* k=binID#,    */
  1106. assignid_map |= m;
  1107. if (k < 8) {
  1108. quintet[0] = 0x38; /* 1st dft ID<8    */
  1109. } else {
  1110. quintet[0] = 0x31; /* 1st ID>=8    */
  1111. }
  1112. k &= 0x07;
  1113. quintet[1] = g2q_tab[k];
  1114. val &= 0x00ff; /* AssignID 1stQuintet,AH=001xxxxx  */
  1115. m = quintet[0] << 8;
  1116. val |= m;
  1117. fun_scam(dev, &val);
  1118. val &= 0x00ff; /* AssignID 2ndQuintet,AH=001xxxxx */
  1119. m = quintet[1] << 8;
  1120. val |= m;
  1121. fun_scam(dev, &val);
  1122. goto TCM_SYNC;
  1123. }
  1124. void is870(unsigned long host, unsigned int wkport)
  1125. {
  1126. unsigned int tmport;
  1127. unsigned char i, j, k, rmb, n;
  1128. unsigned short int m;
  1129. static unsigned char mbuf[512];
  1130. static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6};
  1131. static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
  1132. static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
  1133. static unsigned char synu[6] = {0x80, 1, 3, 1, 0x0c, 0x0e};
  1134. static unsigned char synw[6] = {0x80, 1, 3, 1, 0x0c, 0x07};
  1135. static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0};
  1136. struct atp_unit *dev = &atp_unit[host];
  1137. sync_idu = 0;
  1138. tmport = wkport + 0x3a;
  1139. outb((unsigned char) (inb(tmport) | 0x10), tmport);
  1140. for (i = 0; i < 16; i++) {
  1141. if ((dev->chip_veru != 4) && (i > 7)) {
  1142. break;
  1143. }
  1144. m = 1;
  1145. m = m << i;
  1146. if ((m & dev->active_idu) != 0) {
  1147. continue;
  1148. }
  1149. if (i == dev->host_idu) {
  1150. printk(KERN_INFO "         ID: %2d  Host Adaptern", dev->host_idu);
  1151. continue;
  1152. }
  1153. tmport = wkport + 0x1b;
  1154. if (dev->chip_veru == 4) {
  1155.    outb(0x01, tmport);
  1156. }
  1157. else
  1158. {
  1159.    outb(0x00, tmport);
  1160. }
  1161. tmport = wkport + 1;
  1162. outb(0x08, tmport++);
  1163. outb(0x7f, tmport++);
  1164. outb(satn[0], tmport++);
  1165. outb(satn[1], tmport++);
  1166. outb(satn[2], tmport++);
  1167. outb(satn[3], tmport++);
  1168. outb(satn[4], tmport++);
  1169. outb(satn[5], tmport++);
  1170. tmport += 0x06;
  1171. outb(0, tmport);
  1172. tmport += 0x02;
  1173. outb(dev->id[i].devspu, tmport++);
  1174. outb(0, tmport++);
  1175. outb(satn[6], tmport++);
  1176. outb(satn[7], tmport++);
  1177. j = i;
  1178. if ((j & 0x08) != 0) {
  1179. j = (j & 0x07) | 0x40;
  1180. }
  1181. outb(j, tmport);
  1182. tmport += 0x03;
  1183. outb(satn[8], tmport);
  1184. tmport += 0x07;
  1185. while ((inb(tmport) & 0x80) == 0x00);
  1186. tmport -= 0x08;
  1187. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1188. continue;
  1189. }
  1190. while (inb(tmport) != 0x8e);
  1191. dev->active_idu |= m;
  1192. tmport = wkport + 0x10;
  1193. outb(0x30, tmport);
  1194. tmport = wkport + 0x04;
  1195. outb(0x00, tmport);
  1196. phase_cmd:
  1197. tmport = wkport + 0x18;
  1198. outb(0x08, tmport);
  1199. tmport += 0x07;
  1200. while ((inb(tmport) & 0x80) == 0x00);
  1201. tmport -= 0x08;
  1202. j = inb(tmport);
  1203. if (j != 0x16) {
  1204. tmport = wkport + 0x10;
  1205. outb(0x41, tmport);
  1206. goto phase_cmd;
  1207. }
  1208. sel_ok:
  1209. tmport = wkport + 3;
  1210. outb(inqd[0], tmport++);
  1211. outb(inqd[1], tmport++);
  1212. outb(inqd[2], tmport++);
  1213. outb(inqd[3], tmport++);
  1214. outb(inqd[4], tmport++);
  1215. outb(inqd[5], tmport);
  1216. tmport += 0x07;
  1217. outb(0, tmport);
  1218. tmport += 0x02;
  1219. outb(dev->id[i].devspu, tmport++);
  1220. outb(0, tmport++);
  1221. outb(inqd[6], tmport++);
  1222. outb(inqd[7], tmport++);
  1223. tmport += 0x03;
  1224. outb(inqd[8], tmport);
  1225. tmport += 0x07;
  1226. while ((inb(tmport) & 0x80) == 0x00);
  1227. tmport -= 0x08;
  1228. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1229. continue;
  1230. }
  1231. while (inb(tmport) != 0x8e);
  1232. tmport = wkport + 0x1b;
  1233. if (dev->chip_veru == 4) {
  1234. outb(0x00, tmport);
  1235. }
  1236. tmport = wkport + 0x18;
  1237. outb(0x08, tmport);
  1238. tmport += 0x07;
  1239. j = 0;
  1240. rd_inq_data:
  1241. k = inb(tmport);
  1242. if ((k & 0x01) != 0) {
  1243. tmport -= 0x06;
  1244. mbuf[j++] = inb(tmport);
  1245. tmport += 0x06;
  1246. goto rd_inq_data;
  1247. }
  1248. if ((k & 0x80) == 0) {
  1249. goto rd_inq_data;
  1250. }
  1251. tmport -= 0x08;
  1252. j = inb(tmport);
  1253. if (j == 0x16) {
  1254. goto inq_ok;
  1255. }
  1256. tmport = wkport + 0x10;
  1257. outb(0x46, tmport);
  1258. tmport += 0x02;
  1259. outb(0, tmport++);
  1260. outb(0, tmport++);
  1261. outb(0, tmport++);
  1262. tmport += 0x03;
  1263. outb(0x08, tmport);
  1264. tmport += 0x07;
  1265. while ((inb(tmport) & 0x80) == 0x00);
  1266. tmport -= 0x08;
  1267. if (inb(tmport) != 0x16) {
  1268. goto sel_ok;
  1269. }
  1270. inq_ok:
  1271. mbuf[36] = 0;
  1272. printk(KERN_INFO "         ID: %2d  %sn", i, &mbuf[8]);
  1273. dev->id[i].devtypeu = mbuf[0];
  1274. rmb = mbuf[1];
  1275. n = mbuf[7];
  1276. if (dev->chip_veru != 4) {
  1277. goto not_wide;
  1278. }
  1279. if ((mbuf[7] & 0x60) == 0) {
  1280. goto not_wide;
  1281. }
  1282. if ((dev->global_map & 0x20) == 0) {
  1283. goto not_wide;
  1284. }
  1285. tmport = wkport + 0x1b;
  1286. outb(0x01, tmport);
  1287. tmport = wkport + 3;
  1288. outb(satn[0], tmport++);
  1289. outb(satn[1], tmport++);
  1290. outb(satn[2], tmport++);
  1291. outb(satn[3], tmport++);
  1292. outb(satn[4], tmport++);
  1293. outb(satn[5], tmport++);
  1294. tmport += 0x06;
  1295. outb(0, tmport);
  1296. tmport += 0x02;
  1297. outb(dev->id[i].devspu, tmport++);
  1298. outb(0, tmport++);
  1299. outb(satn[6], tmport++);
  1300. outb(satn[7], tmport++);
  1301. tmport += 0x03;
  1302. outb(satn[8], tmport);
  1303. tmport += 0x07;
  1304. while ((inb(tmport) & 0x80) == 0x00);
  1305. tmport -= 0x08;
  1306. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1307. continue;
  1308. }
  1309. while (inb(tmport) != 0x8e);
  1310. try_wide:
  1311. j = 0;
  1312. tmport = wkport + 0x14;
  1313. outb(0x05, tmport);
  1314. tmport += 0x04;
  1315. outb(0x20, tmport);
  1316. tmport += 0x07;
  1317. while ((inb(tmport) & 0x80) == 0) {
  1318. if ((inb(tmport) & 0x01) != 0) {
  1319. tmport -= 0x06;
  1320. outb(wide[j++], tmport);
  1321. tmport += 0x06;
  1322. }
  1323. }
  1324. tmport -= 0x08;
  1325. while ((inb(tmport) & 0x80) == 0x00);
  1326. j = inb(tmport) & 0x0f;
  1327. if (j == 0x0f) {
  1328. goto widep_in;
  1329. }
  1330. if (j == 0x0a) {
  1331. goto widep_cmd;
  1332. }
  1333. if (j == 0x0e) {
  1334. goto try_wide;
  1335. }
  1336. continue;
  1337. widep_out:
  1338. tmport = wkport + 0x18;
  1339. outb(0x20, tmport);
  1340. tmport += 0x07;
  1341. while ((inb(tmport) & 0x80) == 0) {
  1342. if ((inb(tmport) & 0x01) != 0) {
  1343. tmport -= 0x06;
  1344. outb(0, tmport);
  1345. tmport += 0x06;
  1346. }
  1347. }
  1348. tmport -= 0x08;
  1349. j = inb(tmport) & 0x0f;
  1350. if (j == 0x0f) {
  1351. goto widep_in;
  1352. }
  1353. if (j == 0x0a) {
  1354. goto widep_cmd;
  1355. }
  1356. if (j == 0x0e) {
  1357. goto widep_out;
  1358. }
  1359. continue;
  1360. widep_in:
  1361. tmport = wkport + 0x14;
  1362. outb(0xff, tmport);
  1363. tmport += 0x04;
  1364. outb(0x20, tmport);
  1365. tmport += 0x07;
  1366. k = 0;
  1367. widep_in1:
  1368. j = inb(tmport);
  1369. if ((j & 0x01) != 0) {
  1370. tmport -= 0x06;
  1371. mbuf[k++] = inb(tmport);
  1372. tmport += 0x06;
  1373. goto widep_in1;
  1374. }
  1375. if ((j & 0x80) == 0x00) {
  1376. goto widep_in1;
  1377. }
  1378. tmport -= 0x08;
  1379. j = inb(tmport) & 0x0f;
  1380. if (j == 0x0f) {
  1381. goto widep_in;
  1382. }
  1383. if (j == 0x0a) {
  1384. goto widep_cmd;
  1385. }
  1386. if (j == 0x0e) {
  1387. goto widep_out;
  1388. }
  1389. continue;
  1390. widep_cmd:
  1391. tmport = wkport + 0x10;
  1392. outb(0x30, tmport);
  1393. tmport = wkport + 0x14;
  1394. outb(0x00, tmport);
  1395. tmport += 0x04;
  1396. outb(0x08, tmport);
  1397. tmport += 0x07;
  1398. while ((inb(tmport) & 0x80) == 0x00);
  1399. tmport -= 0x08;
  1400. j = inb(tmport);
  1401. if (j != 0x16) {
  1402. if (j == 0x4e) {
  1403. goto widep_out;
  1404. }
  1405. continue;
  1406. }
  1407. if (mbuf[0] != 0x01) {
  1408. goto not_wide;
  1409. }
  1410. if (mbuf[1] != 0x02) {
  1411. goto not_wide;
  1412. }
  1413. if (mbuf[2] != 0x03) {
  1414. goto not_wide;
  1415. }
  1416. if (mbuf[3] != 0x01) {
  1417. goto not_wide;
  1418. }
  1419. m = 1;
  1420. m = m << i;
  1421. dev->wide_idu |= m;
  1422. not_wide:
  1423. if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
  1424.     ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
  1425. {
  1426. goto set_sync;
  1427. }
  1428. continue;
  1429. set_sync:
  1430. tmport = wkport + 0x1b;
  1431. j = 0;
  1432. if ((m & dev->wide_idu) != 0) {
  1433. j |= 0x01;
  1434. }
  1435. outb(j, tmport);
  1436. tmport = wkport + 3;
  1437. outb(satn[0], tmport++);
  1438. outb(satn[1], tmport++);
  1439. outb(satn[2], tmport++);
  1440. outb(satn[3], tmport++);
  1441. outb(satn[4], tmport++);
  1442. outb(satn[5], tmport++);
  1443. tmport += 0x06;
  1444. outb(0, tmport);
  1445. tmport += 0x02;
  1446. outb(dev->id[i].devspu, tmport++);
  1447. outb(0, tmport++);
  1448. outb(satn[6], tmport++);
  1449. outb(satn[7], tmport++);
  1450. tmport += 0x03;
  1451. outb(satn[8], tmport);
  1452. tmport += 0x07;
  1453. while ((inb(tmport) & 0x80) == 0x00);
  1454. tmport -= 0x08;
  1455. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1456. continue;
  1457. }
  1458. while (inb(tmport) != 0x8e);
  1459. try_sync:
  1460. j = 0;
  1461. tmport = wkport + 0x14;
  1462. outb(0x06, tmport);
  1463. tmport += 0x04;
  1464. outb(0x20, tmport);
  1465. tmport += 0x07;
  1466. while ((inb(tmport) & 0x80) == 0) {
  1467. if ((inb(tmport) & 0x01) != 0) {
  1468. tmport -= 0x06;
  1469. if ((m & dev->wide_idu) != 0) {
  1470. outb(synw[j++], tmport);
  1471. } else {
  1472. if ((m & dev->ultra_map) != 0) {
  1473. outb(synu[j++], tmport);
  1474. } else {
  1475. outb(synn[j++], tmport);
  1476. }
  1477. }
  1478. tmport += 0x06;
  1479. }
  1480. }
  1481. tmport -= 0x08;
  1482. while ((inb(tmport) & 0x80) == 0x00);
  1483. j = inb(tmport) & 0x0f;
  1484. if (j == 0x0f) {
  1485. goto phase_ins;
  1486. }
  1487. if (j == 0x0a) {
  1488. goto phase_cmds;
  1489. }
  1490. if (j == 0x0e) {
  1491. goto try_sync;
  1492. }
  1493. continue;
  1494. phase_outs:
  1495. tmport = wkport + 0x18;
  1496. outb(0x20, tmport);
  1497. tmport += 0x07;
  1498. while ((inb(tmport) & 0x80) == 0x00) {
  1499. if ((inb(tmport) & 0x01) != 0x00) {
  1500. tmport -= 0x06;
  1501. outb(0x00, tmport);
  1502. tmport += 0x06;
  1503. }
  1504. }
  1505. tmport -= 0x08;
  1506. j = inb(tmport);
  1507. if (j == 0x85) {
  1508. goto tar_dcons;
  1509. }
  1510. j &= 0x0f;
  1511. if (j == 0x0f) {
  1512. goto phase_ins;
  1513. }
  1514. if (j == 0x0a) {
  1515. goto phase_cmds;
  1516. }
  1517. if (j == 0x0e) {
  1518. goto phase_outs;
  1519. }
  1520. continue;
  1521. phase_ins:
  1522. tmport = wkport + 0x14;
  1523. outb(0xff, tmport);
  1524. tmport += 0x04;
  1525. outb(0x20, tmport);
  1526. tmport += 0x07;
  1527. k = 0;
  1528. phase_ins1:
  1529. j = inb(tmport);
  1530. if ((j & 0x01) != 0x00) {
  1531. tmport -= 0x06;
  1532. mbuf[k++] = inb(tmport);
  1533. tmport += 0x06;
  1534. goto phase_ins1;
  1535. }
  1536. if ((j & 0x80) == 0x00) {
  1537. goto phase_ins1;
  1538. }
  1539. tmport -= 0x08;
  1540. while ((inb(tmport) & 0x80) == 0x00);
  1541. j = inb(tmport);
  1542. if (j == 0x85) {
  1543. goto tar_dcons;
  1544. }
  1545. j &= 0x0f;
  1546. if (j == 0x0f) {
  1547. goto phase_ins;
  1548. }
  1549. if (j == 0x0a) {
  1550. goto phase_cmds;
  1551. }
  1552. if (j == 0x0e) {
  1553. goto phase_outs;
  1554. }
  1555. continue;
  1556. phase_cmds:
  1557. tmport = wkport + 0x10;
  1558. outb(0x30, tmport);
  1559. tar_dcons:
  1560. tmport = wkport + 0x14;
  1561. outb(0x00, tmport);
  1562. tmport += 0x04;
  1563. outb(0x08, tmport);
  1564. tmport += 0x07;
  1565. while ((inb(tmport) & 0x80) == 0x00);
  1566. tmport -= 0x08;
  1567. j = inb(tmport);
  1568. if (j != 0x16) {
  1569. continue;
  1570. }
  1571. if (mbuf[0] != 0x01) {
  1572. continue;
  1573. }
  1574. if (mbuf[1] != 0x03) {
  1575. continue;
  1576. }
  1577. if (mbuf[4] == 0x00) {
  1578. continue;
  1579. }
  1580. if (mbuf[3] > 0x64) {
  1581. continue;
  1582. }
  1583. if (mbuf[4] > 0x0c) {
  1584. mbuf[4] = 0x0c;
  1585. }
  1586. dev->id[i].devspu = mbuf[4];
  1587. if ((mbuf[3] < 0x0d) && (rmb == 0)) {
  1588. j = 0xa0;
  1589. goto set_syn_ok;
  1590. }
  1591. if (mbuf[3] < 0x1a) {
  1592. j = 0x20;
  1593. goto set_syn_ok;
  1594. }
  1595. if (mbuf[3] < 0x33) {
  1596. j = 0x40;
  1597. goto set_syn_ok;
  1598. }
  1599. if (mbuf[3] < 0x4c) {
  1600. j = 0x50;
  1601. goto set_syn_ok;
  1602. }
  1603. j = 0x60;
  1604.       set_syn_ok:
  1605. dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
  1606. }
  1607. tmport = wkport + 0x3a;
  1608. outb((unsigned char) (inb(tmport) & 0xef), tmport);
  1609. }
  1610. void is880(unsigned long host, unsigned int wkport)
  1611. {
  1612. unsigned int tmport;
  1613. unsigned char i, j, k, rmb, n, lvdmode;
  1614. unsigned short int m;
  1615. static unsigned char mbuf[512];
  1616. static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6};
  1617. static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
  1618. static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
  1619. unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
  1620. static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e};
  1621. unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
  1622. static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0};
  1623. static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
  1624. struct atp_unit *dev = &atp_unit[host];
  1625. sync_idu = 0;
  1626. lvdmode=inb(wkport + 0x3f) & 0x40;
  1627. for (i = 0; i < 16; i++) {
  1628. m = 1;
  1629. m = m << i;
  1630. if ((m & dev->active_idu) != 0) {
  1631. continue;
  1632. }
  1633. if (i == dev->host_idu) {
  1634. printk(KERN_INFO "         ID: %2d  Host Adaptern", dev->host_idu);
  1635. continue;
  1636. }
  1637. tmport = wkport + 0x5b;
  1638. outb(0x01, tmport);
  1639. tmport = wkport + 0x41;
  1640. outb(0x08, tmport++);
  1641. outb(0x7f, tmport++);
  1642. outb(satn[0], tmport++);
  1643. outb(satn[1], tmport++);
  1644. outb(satn[2], tmport++);
  1645. outb(satn[3], tmport++);
  1646. outb(satn[4], tmport++);
  1647. outb(satn[5], tmport++);
  1648. tmport += 0x06;
  1649. outb(0, tmport);
  1650. tmport += 0x02;
  1651. outb(dev->id[i].devspu, tmport++);
  1652. outb(0, tmport++);
  1653. outb(satn[6], tmport++);
  1654. outb(satn[7], tmport++);
  1655. j = i;
  1656. if ((j & 0x08) != 0) {
  1657. j = (j & 0x07) | 0x40;
  1658. }
  1659. outb(j, tmport);
  1660. tmport += 0x03;
  1661. outb(satn[8], tmport);
  1662. tmport += 0x07;
  1663. while ((inb(tmport) & 0x80) == 0x00);
  1664. tmport -= 0x08;
  1665. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1666. continue;
  1667. }
  1668. while (inb(tmport) != 0x8e);
  1669. dev->active_idu |= m;
  1670. tmport = wkport + 0x50;
  1671. outb(0x30, tmport);
  1672. tmport = wkport + 0x54;
  1673. outb(0x00, tmport);
  1674. phase_cmd:
  1675. tmport = wkport + 0x58;
  1676. outb(0x08, tmport);
  1677. tmport += 0x07;
  1678. while ((inb(tmport) & 0x80) == 0x00);
  1679. tmport -= 0x08;
  1680. j = inb(tmport);
  1681. if (j != 0x16) {
  1682. tmport = wkport + 0x50;
  1683. outb(0x41, tmport);
  1684. goto phase_cmd;
  1685. }
  1686. sel_ok:
  1687. tmport = wkport + 0x43;
  1688. outb(inqd[0], tmport++);
  1689. outb(inqd[1], tmport++);
  1690. outb(inqd[2], tmport++);
  1691. outb(inqd[3], tmport++);
  1692. outb(inqd[4], tmport++);
  1693. outb(inqd[5], tmport);
  1694. tmport += 0x07;
  1695. outb(0, tmport);
  1696. tmport += 0x02;
  1697. outb(dev->id[i].devspu, tmport++);
  1698. outb(0, tmport++);
  1699. outb(inqd[6], tmport++);
  1700. outb(inqd[7], tmport++);
  1701. tmport += 0x03;
  1702. outb(inqd[8], tmport);
  1703. tmport += 0x07;
  1704. while ((inb(tmport) & 0x80) == 0x00);
  1705. tmport -= 0x08;
  1706. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1707. continue;
  1708. }
  1709. while (inb(tmport) != 0x8e);
  1710. tmport = wkport + 0x5b;
  1711. outb(0x00, tmport);
  1712. tmport = wkport + 0x58;
  1713. outb(0x08, tmport);
  1714. tmport += 0x07;
  1715. j = 0;
  1716. rd_inq_data:
  1717. k = inb(tmport);
  1718. if ((k & 0x01) != 0) {
  1719. tmport -= 0x06;
  1720. mbuf[j++] = inb(tmport);
  1721. tmport += 0x06;
  1722. goto rd_inq_data;
  1723. }
  1724. if ((k & 0x80) == 0) {
  1725. goto rd_inq_data;
  1726. }
  1727. tmport -= 0x08;
  1728. j = inb(tmport);
  1729. if (j == 0x16) {
  1730. goto inq_ok;
  1731. }
  1732. tmport = wkport + 0x50;
  1733. outb(0x46, tmport);
  1734. tmport += 0x02;
  1735. outb(0, tmport++);
  1736. outb(0, tmport++);
  1737. outb(0, tmport++);
  1738. tmport += 0x03;
  1739. outb(0x08, tmport);
  1740. tmport += 0x07;
  1741. while ((inb(tmport) & 0x80) == 0x00);
  1742. tmport -= 0x08;
  1743. if (inb(tmport) != 0x16) {
  1744. goto sel_ok;
  1745. }
  1746. inq_ok:
  1747. mbuf[36] = 0;
  1748. printk(KERN_INFO "         ID: %2d  %sn", i, &mbuf[8]);
  1749. dev->id[i].devtypeu = mbuf[0];
  1750. rmb = mbuf[1];
  1751. n = mbuf[7];
  1752. if ((mbuf[7] & 0x60) == 0) {
  1753. goto not_wide;
  1754. }
  1755. if ((i < 8) && ((dev->global_map & 0x20) == 0)) {
  1756. goto not_wide;
  1757. }
  1758. if (lvdmode == 0)
  1759. {
  1760.    goto chg_wide;
  1761. }
  1762. if (dev->sp[i] != 0x04)   // force u2
  1763. {
  1764.    goto chg_wide;
  1765. }
  1766. tmport = wkport + 0x5b;
  1767. outb(0x01, tmport);
  1768. tmport = wkport + 0x43;
  1769. outb(satn[0], tmport++);
  1770. outb(satn[1], tmport++);
  1771. outb(satn[2], tmport++);
  1772. outb(satn[3], tmport++);
  1773. outb(satn[4], tmport++);
  1774. outb(satn[5], tmport++);
  1775. tmport += 0x06;
  1776. outb(0, tmport);
  1777. tmport += 0x02;
  1778. outb(dev->id[i].devspu, tmport++);
  1779. outb(0, tmport++);
  1780. outb(satn[6], tmport++);
  1781. outb(satn[7], tmport++);
  1782. tmport += 0x03;
  1783. outb(satn[8], tmport);
  1784. tmport += 0x07;
  1785. while ((inb(tmport) & 0x80) == 0x00);
  1786. tmport -= 0x08;
  1787. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1788. continue;
  1789. }
  1790. while (inb(tmport) != 0x8e);
  1791. try_u3:
  1792. j = 0;
  1793. tmport = wkport + 0x54;
  1794. outb(0x09, tmport);
  1795. tmport += 0x04;
  1796. outb(0x20, tmport);
  1797. tmport += 0x07;
  1798. while ((inb(tmport) & 0x80) == 0) {
  1799. if ((inb(tmport) & 0x01) != 0) {
  1800. tmport -= 0x06;
  1801. outb(u3[j++], tmport);
  1802. tmport += 0x06;
  1803. }
  1804. }
  1805. tmport -= 0x08;
  1806. while ((inb(tmport) & 0x80) == 0x00);
  1807. j = inb(tmport) & 0x0f;
  1808. if (j == 0x0f) {
  1809. goto u3p_in;
  1810. }
  1811. if (j == 0x0a) {
  1812. goto u3p_cmd;
  1813. }
  1814. if (j == 0x0e) {
  1815. goto try_u3;
  1816. }
  1817. continue;
  1818. u3p_out:
  1819. tmport = wkport + 0x58;
  1820. outb(0x20, tmport);
  1821. tmport += 0x07;
  1822. while ((inb(tmport) & 0x80) == 0) {
  1823. if ((inb(tmport) & 0x01) != 0) {
  1824. tmport -= 0x06;
  1825. outb(0, tmport);
  1826. tmport += 0x06;
  1827. }
  1828. }
  1829. tmport -= 0x08;
  1830. j = inb(tmport) & 0x0f;
  1831. if (j == 0x0f) {
  1832. goto u3p_in;
  1833. }
  1834. if (j == 0x0a) {
  1835. goto u3p_cmd;
  1836. }
  1837. if (j == 0x0e) {
  1838. goto u3p_out;
  1839. }
  1840. continue;
  1841. u3p_in:
  1842. tmport = wkport + 0x54;
  1843. outb(0x09, tmport);
  1844. tmport += 0x04;
  1845. outb(0x20, tmport);
  1846. tmport += 0x07;
  1847. k = 0;
  1848. u3p_in1:
  1849. j = inb(tmport);
  1850. if ((j & 0x01) != 0) {
  1851. tmport -= 0x06;
  1852. mbuf[k++] = inb(tmport);
  1853. tmport += 0x06;
  1854. goto u3p_in1;
  1855. }
  1856. if ((j & 0x80) == 0x00) {
  1857. goto u3p_in1;
  1858. }
  1859. tmport -= 0x08;
  1860. j = inb(tmport) & 0x0f;
  1861. if (j == 0x0f) {
  1862. goto u3p_in;
  1863. }
  1864. if (j == 0x0a) {
  1865. goto u3p_cmd;
  1866. }
  1867. if (j == 0x0e) {
  1868. goto u3p_out;
  1869. }
  1870. continue;
  1871. u3p_cmd:
  1872. tmport = wkport + 0x50;
  1873. outb(0x30, tmport);
  1874. tmport = wkport + 0x54;
  1875. outb(0x00, tmport);
  1876. tmport += 0x04;
  1877. outb(0x08, tmport);
  1878. tmport += 0x07;
  1879. while ((inb(tmport) & 0x80) == 0x00);
  1880. tmport -= 0x08;
  1881. j = inb(tmport);
  1882. if (j != 0x16) {
  1883. if (j == 0x4e) {
  1884. goto u3p_out;
  1885. }
  1886. continue;
  1887. }
  1888. if (mbuf[0] != 0x01) {
  1889. goto chg_wide;
  1890. }
  1891. if (mbuf[1] != 0x06) {
  1892. goto chg_wide;
  1893. }
  1894. if (mbuf[2] != 0x04) {
  1895. goto chg_wide;
  1896. }
  1897. if (mbuf[3] == 0x09) {
  1898.    m = 1;
  1899.    m = m << i;
  1900.    dev->wide_idu |= m;
  1901.    dev->id[i].devspu = 0xce;
  1902.    continue;
  1903. }
  1904. chg_wide:
  1905. tmport = wkport + 0x5b;
  1906. outb(0x01, tmport);
  1907. tmport = wkport + 0x43;
  1908. outb(satn[0], tmport++);
  1909. outb(satn[1], tmport++);
  1910. outb(satn[2], tmport++);
  1911. outb(satn[3], tmport++);
  1912. outb(satn[4], tmport++);
  1913. outb(satn[5], tmport++);
  1914. tmport += 0x06;
  1915. outb(0, tmport);
  1916. tmport += 0x02;
  1917. outb(dev->id[i].devspu, tmport++);
  1918. outb(0, tmport++);
  1919. outb(satn[6], tmport++);
  1920. outb(satn[7], tmport++);
  1921. tmport += 0x03;
  1922. outb(satn[8], tmport);
  1923. tmport += 0x07;
  1924. while ((inb(tmport) & 0x80) == 0x00);
  1925. tmport -= 0x08;
  1926. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  1927. continue;
  1928. }
  1929. while (inb(tmport) != 0x8e);
  1930. try_wide:
  1931. j = 0;
  1932. tmport = wkport + 0x54;
  1933. outb(0x05, tmport);
  1934. tmport += 0x04;
  1935. outb(0x20, tmport);
  1936. tmport += 0x07;
  1937. while ((inb(tmport) & 0x80) == 0) {
  1938. if ((inb(tmport) & 0x01) != 0) {
  1939. tmport -= 0x06;
  1940. outb(wide[j++], tmport);
  1941. tmport += 0x06;
  1942. }
  1943. }
  1944. tmport -= 0x08;
  1945. while ((inb(tmport) & 0x80) == 0x00);
  1946. j = inb(tmport) & 0x0f;
  1947. if (j == 0x0f) {
  1948. goto widep_in;
  1949. }
  1950. if (j == 0x0a) {
  1951. goto widep_cmd;
  1952. }
  1953. if (j == 0x0e) {
  1954. goto try_wide;
  1955. }
  1956. continue;
  1957. widep_out:
  1958. tmport = wkport + 0x58;
  1959. outb(0x20, tmport);
  1960. tmport += 0x07;
  1961. while ((inb(tmport) & 0x80) == 0) {
  1962. if ((inb(tmport) & 0x01) != 0) {
  1963. tmport -= 0x06;
  1964. outb(0, tmport);
  1965. tmport += 0x06;
  1966. }
  1967. }
  1968. tmport -= 0x08;
  1969. j = inb(tmport) & 0x0f;
  1970. if (j == 0x0f) {
  1971. goto widep_in;
  1972. }
  1973. if (j == 0x0a) {
  1974. goto widep_cmd;
  1975. }
  1976. if (j == 0x0e) {
  1977. goto widep_out;
  1978. }
  1979. continue;
  1980. widep_in:
  1981. tmport = wkport + 0x54;
  1982. outb(0xff, tmport);
  1983. tmport += 0x04;
  1984. outb(0x20, tmport);
  1985. tmport += 0x07;
  1986. k = 0;
  1987. widep_in1:
  1988. j = inb(tmport);
  1989. if ((j & 0x01) != 0) {
  1990. tmport -= 0x06;
  1991. mbuf[k++] = inb(tmport);
  1992. tmport += 0x06;
  1993. goto widep_in1;
  1994. }
  1995. if ((j & 0x80) == 0x00) {
  1996. goto widep_in1;
  1997. }
  1998. tmport -= 0x08;
  1999. j = inb(tmport) & 0x0f;
  2000. if (j == 0x0f) {
  2001. goto widep_in;
  2002. }
  2003. if (j == 0x0a) {
  2004. goto widep_cmd;
  2005. }
  2006. if (j == 0x0e) {
  2007. goto widep_out;
  2008. }
  2009. continue;
  2010. widep_cmd:
  2011. tmport = wkport + 0x50;
  2012. outb(0x30, tmport);
  2013. tmport = wkport + 0x54;
  2014. outb(0x00, tmport);
  2015. tmport += 0x04;
  2016. outb(0x08, tmport);
  2017. tmport += 0x07;
  2018. while ((inb(tmport) & 0x80) == 0x00);
  2019. tmport -= 0x08;
  2020. j = inb(tmport);
  2021. if (j != 0x16) {
  2022. if (j == 0x4e) {
  2023. goto widep_out;
  2024. }
  2025. continue;
  2026. }
  2027. if (mbuf[0] != 0x01) {
  2028. goto not_wide;
  2029. }
  2030. if (mbuf[1] != 0x02) {
  2031. goto not_wide;
  2032. }
  2033. if (mbuf[2] != 0x03) {
  2034. goto not_wide;
  2035. }
  2036. if (mbuf[3] != 0x01) {
  2037. goto not_wide;
  2038. }
  2039. m = 1;
  2040. m = m << i;
  2041. dev->wide_idu |= m;
  2042. not_wide:
  2043. if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) ||
  2044.     ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0)))
  2045. {
  2046. m = 1;
  2047. m = m << i;
  2048. if ((dev->async & m) != 0)
  2049. {
  2050.    goto set_sync;
  2051. }
  2052. }
  2053. continue;
  2054. set_sync:
  2055. if (dev->sp[i] == 0x02)
  2056. {
  2057.    synu[4]=0x0c;
  2058.    synuw[4]=0x0c;
  2059. }
  2060. else
  2061. {
  2062.    if (dev->sp[i] >= 0x03)
  2063.    {
  2064.       synu[4]=0x0a;
  2065.       synuw[4]=0x0a;
  2066.    }
  2067. }
  2068. tmport = wkport + 0x5b;
  2069. j = 0;
  2070. if ((m & dev->wide_idu) != 0) {
  2071. j |= 0x01;
  2072. }
  2073. outb(j, tmport);
  2074. tmport = wkport + 0x43;
  2075. outb(satn[0], tmport++);
  2076. outb(satn[1], tmport++);
  2077. outb(satn[2], tmport++);
  2078. outb(satn[3], tmport++);
  2079. outb(satn[4], tmport++);
  2080. outb(satn[5], tmport++);
  2081. tmport += 0x06;
  2082. outb(0, tmport);
  2083. tmport += 0x02;
  2084. outb(dev->id[i].devspu, tmport++);
  2085. outb(0, tmport++);
  2086. outb(satn[6], tmport++);
  2087. outb(satn[7], tmport++);
  2088. tmport += 0x03;
  2089. outb(satn[8], tmport);
  2090. tmport += 0x07;
  2091. while ((inb(tmport) & 0x80) == 0x00);
  2092. tmport -= 0x08;
  2093. if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
  2094. continue;
  2095. }
  2096. while (inb(tmport) != 0x8e);
  2097. try_sync:
  2098. j = 0;
  2099. tmport = wkport + 0x54;
  2100. outb(0x06, tmport);
  2101. tmport += 0x04;
  2102. outb(0x20, tmport);
  2103. tmport += 0x07;
  2104. while ((inb(tmport) & 0x80) == 0) {
  2105. if ((inb(tmport) & 0x01) != 0) {
  2106. tmport -= 0x06;
  2107. if ((m & dev->wide_idu) != 0) {
  2108. if ((m & dev->ultra_map) != 0) {
  2109. outb(synuw[j++], tmport);
  2110. } else {
  2111. outb(synw[j++], tmport);
  2112. }
  2113. } else {
  2114. if ((m & dev->ultra_map) != 0) {
  2115. outb(synu[j++], tmport);
  2116. } else {
  2117. outb(synn[j++], tmport);
  2118. }
  2119. }
  2120. tmport += 0x06;
  2121. }
  2122. }
  2123. tmport -= 0x08;
  2124. while ((inb(tmport) & 0x80) == 0x00);
  2125. j = inb(tmport) & 0x0f;
  2126. if (j == 0x0f) {
  2127. goto phase_ins;
  2128. }
  2129. if (j == 0x0a) {
  2130. goto phase_cmds;
  2131. }
  2132. if (j == 0x0e) {
  2133. goto try_sync;
  2134. }
  2135. continue;
  2136. phase_outs:
  2137. tmport = wkport + 0x58;
  2138. outb(0x20, tmport);
  2139. tmport += 0x07;
  2140. while ((inb(tmport) & 0x80) == 0x00) {
  2141. if ((inb(tmport) & 0x01) != 0x00) {
  2142. tmport -= 0x06;
  2143. outb(0x00, tmport);
  2144. tmport += 0x06;
  2145. }
  2146. }
  2147. tmport -= 0x08;
  2148. j = inb(tmport);
  2149. if (j == 0x85) {
  2150. goto tar_dcons;
  2151. }
  2152. j &= 0x0f;
  2153. if (j == 0x0f) {
  2154. goto phase_ins;
  2155. }
  2156. if (j == 0x0a) {
  2157. goto phase_cmds;
  2158. }
  2159. if (j == 0x0e) {
  2160. goto phase_outs;
  2161. }
  2162. continue;
  2163. phase_ins:
  2164. tmport = wkport + 0x54;
  2165. outb(0x06, tmport);
  2166. tmport += 0x04;
  2167. outb(0x20, tmport);
  2168. tmport += 0x07;
  2169. k = 0;
  2170. phase_ins1:
  2171. j = inb(tmport);
  2172. if ((j & 0x01) != 0x00) {
  2173. tmport -= 0x06;
  2174. mbuf[k++] = inb(tmport);
  2175. tmport += 0x06;
  2176. goto phase_ins1;
  2177. }
  2178. if ((j & 0x80) == 0x00) {
  2179. goto phase_ins1;
  2180. }
  2181. tmport -= 0x08;
  2182. while ((inb(tmport) & 0x80) == 0x00);
  2183. j = inb(tmport);
  2184. if (j == 0x85) {
  2185. goto tar_dcons;
  2186. }
  2187. j &= 0x0f;
  2188. if (j == 0x0f) {
  2189. goto phase_ins;
  2190. }
  2191. if (j == 0x0a) {
  2192. goto phase_cmds;
  2193. }
  2194. if (j == 0x0e) {
  2195. goto phase_outs;
  2196. }
  2197. continue;
  2198. phase_cmds:
  2199. tmport = wkport + 0x50;
  2200. outb(0x30, tmport);
  2201. tar_dcons:
  2202. tmport = wkport + 0x54;
  2203. outb(0x00, tmport);
  2204. tmport += 0x04;
  2205. outb(0x08, tmport);
  2206. tmport += 0x07;
  2207. while ((inb(tmport) & 0x80) == 0x00);
  2208. tmport -= 0x08;
  2209. j = inb(tmport);
  2210. if (j != 0x16) {
  2211. continue;
  2212. }
  2213. if (mbuf[0] != 0x01) {
  2214. continue;
  2215. }
  2216. if (mbuf[1] != 0x03) {
  2217. continue;
  2218. }
  2219. if (mbuf[4] == 0x00) {
  2220. continue;
  2221. }
  2222. if (mbuf[3] > 0x64) {
  2223. continue;
  2224. }
  2225. if (mbuf[4] > 0x0e) {
  2226. mbuf[4] = 0x0e;
  2227. }
  2228. dev->id[i].devspu = mbuf[4];
  2229. if (mbuf[3] < 0x0c){
  2230. j = 0xb0;
  2231. goto set_syn_ok;
  2232. }
  2233. if ((mbuf[3] < 0x0d) && (rmb == 0)) {
  2234. j = 0xa0;
  2235. goto set_syn_ok;
  2236. }
  2237. if (mbuf[3] < 0x1a) {
  2238. j = 0x20;
  2239. goto set_syn_ok;
  2240. }
  2241. if (mbuf[3] < 0x33) {
  2242. j = 0x40;
  2243. goto set_syn_ok;
  2244. }
  2245. if (mbuf[3] < 0x4c) {
  2246. j = 0x50;
  2247. goto set_syn_ok;
  2248. }
  2249. j = 0x60;
  2250.       set_syn_ok:
  2251. dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j;
  2252. }
  2253. }
  2254. /* return non-zero on detection */
  2255. int atp870u_detect(Scsi_Host_Template * tpnt)
  2256. {
  2257. unsigned char irq, h, k, m;
  2258. unsigned long flags;
  2259. unsigned int base_io, error, tmport;
  2260. unsigned short index = 0;
  2261. struct pci_dev *pdev[3];
  2262. unsigned char chip_ver[3], host_id;
  2263. unsigned short dev_id[3], n;
  2264. struct Scsi_Host *shpnt = NULL;
  2265. int tmpcnt = 0;
  2266. int count = 0;
  2267. static unsigned short devid[9] = {
  2268.   0x8081, 0x8002, 0x8010, 0x8020, 0x8030, 0x8040, 0x8050, 0x8060, 0
  2269. };
  2270. printk(KERN_INFO "aec671x_detect: n");
  2271. if (!pci_present()) {
  2272. printk(KERN_INFO"   NO PCI SUPPORT.n");
  2273. return count;
  2274. }
  2275. tpnt->proc_name = "atp870u";
  2276. for (h = 0; h < 2; h++) {
  2277. struct atp_unit *dev = &atp_unit[h];
  2278. for(k=0;k<16;k++)
  2279. {
  2280. dev->id[k].prd_tableu = kmalloc(1024, GFP_KERNEL);
  2281. dev->id[k].devspu=0x20;
  2282. dev->id[k].devtypeu = 0;
  2283. dev->id[k].curr_req = NULL;
  2284. }
  2285. dev->active_idu = 0;
  2286. dev->wide_idu = 0;
  2287. dev->host_idu = 0x07;
  2288. dev->quhdu = 0;
  2289. dev->quendu = 0;
  2290. pdev[h]=NULL;
  2291. pdev[2]=NULL;
  2292. dev->chip_veru = 0;
  2293. dev->last_cmd = 0xff;
  2294. dev->in_snd = 0;
  2295. dev->in_int = 0;
  2296. for (k = 0; k < qcnt; k++) {
  2297. dev->querequ[k] = 0;
  2298. }
  2299. for (k = 0; k < 16; k++) {
  2300. dev->id[k].curr_req = 0;
  2301. dev->sp[k] = 0x04;
  2302. }
  2303. }
  2304. h = 0;
  2305. while (devid[h] != 0) {
  2306. pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]);
  2307. if (pdev[2] == NULL || pci_enable_device(pdev[2])) {
  2308. h++;
  2309. index = 0;
  2310. continue;
  2311. }
  2312. chip_ver[2] = 0;
  2313. dev_id[2] = devid[h];
  2314. if (devid[h] == 0x8002) {
  2315. error = pci_read_config_byte(pdev[2], 0x08, &chip_ver[2]);
  2316. if (chip_ver[2] < 2) {
  2317. goto nxt_devfn;
  2318. }
  2319. }
  2320. if (devid[h] == 0x8010 || devid[h] == 0x8081 || devid[h] == 0x8050)
  2321. {
  2322. chip_ver[2] = 0x04;
  2323. }
  2324. pdev[tmpcnt] = pdev[2];
  2325. chip_ver[tmpcnt] = chip_ver[2];
  2326. dev_id[tmpcnt] = dev_id[2];
  2327. tmpcnt++;
  2328.       nxt_devfn:
  2329. index++;
  2330. if (index > 3) {
  2331. index = 0;
  2332. h++;
  2333. }
  2334. if(tmpcnt>1)
  2335. break;
  2336. }
  2337. for (h = 0; h < 2; h++) {
  2338. struct atp_unit *dev=&atp_unit[h];
  2339. if (pdev[h]==NULL) {
  2340. return count;
  2341. }
  2342. /* Found an atp870u/w. */
  2343. base_io = pci_resource_start(pdev[h], 0);
  2344. irq = pdev[h]->irq;
  2345. if (dev_id[h] != 0x8081)
  2346. {
  2347.    error = pci_read_config_byte(pdev[h],0x49,&host_id);
  2348.    base_io &= 0xfffffff8;
  2349.    if (check_region(base_io,0x40) != 0)
  2350.    {
  2351.    return 0;
  2352.    }
  2353.    printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d    IO:%x, IRQ:%d.n"
  2354.   ,h, base_io, irq);
  2355.    dev->ioport = base_io;
  2356.    dev->pciport = base_io + 0x20;
  2357.    dev->deviceid = dev_id[h];
  2358.    irqnumu[h] = irq;
  2359.    host_id &= 0x07;
  2360.    dev->host_idu = host_id;
  2361.    dev->chip_veru = chip_ver[h];
  2362.    tmport = base_io + 0x22;
  2363.    dev->scam_on = inb(tmport);
  2364.    tmport += 0x0b;
  2365.    dev->global_map = inb(tmport++);
  2366.    dev->ultra_map = inw(tmport);
  2367.    if (dev->ultra_map == 0) {
  2368.    dev->scam_on = 0x00;
  2369.    dev->global_map = 0x20;
  2370.    dev->ultra_map = 0xffff;
  2371.    }
  2372.    shpnt = scsi_register(tpnt, 4);
  2373.    if(shpnt==NULL)
  2374.    return count;
  2375.    save_flags(flags);
  2376.    cli();
  2377.    if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
  2378.    printk(KERN_ERR "Unable to allocate IRQ for Acard controller.n");
  2379.    goto unregister;
  2380.    }
  2381.    if (chip_ver[h] > 0x07)      /* check if atp876 chip   */
  2382.    {      /* then enable terminator */
  2383.       tmport = base_io + 0x3e;
  2384.       outb(0x00, tmport);
  2385.    }
  2386.    tmport = base_io + 0x3a;
  2387.    k = (inb(tmport) & 0xf3) | 0x10;
  2388.    outb(k, tmport);
  2389.    outb((k & 0xdf), tmport);
  2390.    mydlyu(0x8000);
  2391.    outb(k, tmport);
  2392.    mydlyu(0x8000);
  2393.    tmport = base_io;
  2394.    outb((host_id | 0x08), tmport);
  2395.    tmport += 0x18;
  2396.    outb(0, tmport);
  2397.    tmport += 0x07;
  2398.    while ((inb(tmport) & 0x80) == 0);
  2399.    tmport -= 0x08;
  2400.    inb(tmport);
  2401.    tmport = base_io + 1;
  2402.    outb(8, tmport++);
  2403.    outb(0x7f, tmport);
  2404.    tmport = base_io + 0x11;
  2405.    outb(0x20, tmport);
  2406.    tscam(h);
  2407.    is870(h, base_io);
  2408.    tmport = base_io + 0x3a;
  2409.    outb((inb(tmport) & 0xef), tmport);
  2410.    tmport++;
  2411.    outb((inb(tmport) | 0x20),tmport);
  2412. }
  2413. else
  2414. {
  2415.    base_io &= 0xfffffff8;
  2416.    if (check_region(base_io,0x60) != 0)
  2417.    {
  2418.    return 0;
  2419.    }
  2420.    host_id = inb(base_io + 0x39);
  2421.    host_id >>= 0x04;
  2422.    printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra160 LVD/SE SCSI Adapter: %d    IO:%x, IRQ:%d.n"
  2423.   ,h, base_io, irq);
  2424.    dev->ioport = base_io + 0x40;
  2425.    dev->pciport = base_io + 0x28;
  2426.    dev->deviceid = dev_id[h];
  2427.    irqnumu[h] = irq;
  2428.    dev->host_idu = host_id;
  2429.    dev->chip_veru = chip_ver[h];
  2430.    tmport = base_io + 0x22;
  2431.    dev->scam_on = inb(tmport);
  2432.    tmport += 0x13;
  2433.    dev->global_map = inb(tmport);
  2434.    tmport += 0x07;
  2435.    dev->ultra_map = inw(tmport);
  2436.    n=0x3f09;
  2437. next_fblk:
  2438.    if (n >= 0x4000)
  2439.    {
  2440.       goto flash_ok;
  2441.    }
  2442.    m=0;
  2443.    outw(n,base_io + 0x34);
  2444.    n += 0x0002;
  2445.    if (inb(base_io + 0x30) == 0xff)
  2446.    {
  2447.       goto flash_ok;
  2448.    }
  2449.    dev->sp[m++]=inb(base_io + 0x30);
  2450.    dev->sp[m++]=inb(base_io + 0x31);
  2451.    dev->sp[m++]=inb(base_io + 0x32);
  2452.    dev->sp[m++]=inb(base_io + 0x33);
  2453.    outw(n,base_io + 0x34);
  2454.    n += 0x0002;
  2455.    dev->sp[m++]=inb(base_io + 0x30);
  2456.    dev->sp[m++]=inb(base_io + 0x31);
  2457.    dev->sp[m++]=inb(base_io + 0x32);
  2458.    dev->sp[m++]=inb(base_io + 0x33);
  2459.    outw(n,base_io + 0x34);
  2460.    n += 0x0002;
  2461.    dev->sp[m++]=inb(base_io + 0x30);
  2462.    dev->sp[m++]=inb(base_io + 0x31);
  2463.    dev->sp[m++]=inb(base_io + 0x32);
  2464.    dev->sp[m++]=inb(base_io + 0x33);
  2465.    outw(n,base_io + 0x34);
  2466.    n += 0x0002;
  2467.    dev->sp[m++]=inb(base_io + 0x30);
  2468.    dev->sp[m++]=inb(base_io + 0x31);
  2469.    dev->sp[m++]=inb(base_io + 0x32);
  2470.    dev->sp[m++]=inb(base_io + 0x33);
  2471.    n += 0x0018;
  2472.    goto next_fblk;
  2473. flash_ok:
  2474.    outw(0,base_io + 0x34);
  2475.    dev->ultra_map=0;
  2476.    dev->async = 0;
  2477.    for (k=0; k < 16; k++)
  2478.    {
  2479.        n=1;
  2480.        n = n << k;
  2481.        if (dev->sp[k] > 1)
  2482.        {
  2483.   dev->ultra_map |= n;
  2484.        }
  2485.        else
  2486.        {
  2487.   if (dev->sp[k] == 0)
  2488.   {
  2489.      dev->async |= n;
  2490.   }
  2491.        }
  2492.    }
  2493.    dev->async = ~(dev->async);
  2494.    outb(dev->global_map,base_io + 0x35);
  2495.    shpnt = scsi_register(tpnt, 4);
  2496.    if(shpnt==NULL)
  2497.    return count;
  2498.    save_flags(flags);
  2499.    cli();
  2500.    if (request_irq(irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", dev)) {
  2501.    printk(KERN_ERR "Unable to allocate IRQ for Acard controller.n");
  2502.    goto unregister;
  2503.    }
  2504.    tmport = base_io + 0x38;
  2505.    k = inb(tmport) & 0x80;
  2506.    outb(k, tmport);
  2507.    tmport += 0x03;
  2508.    outb(0x20, tmport);
  2509.    mydlyu(0x8000);
  2510.    outb(0, tmport);
  2511.    mydlyu(0x8000);
  2512.    tmport = base_io + 0x5b;
  2513.    inb(tmport);
  2514.    tmport -= 0x04;
  2515.    inb(tmport);
  2516.    tmport = base_io + 0x40;
  2517.    outb((host_id | 0x08), tmport);
  2518.    tmport += 0x18;
  2519.    outb(0, tmport);
  2520.    tmport += 0x07;
  2521.    while ((inb(tmport) & 0x80) == 0);
  2522.    tmport -= 0x08;
  2523.    inb(tmport);
  2524.    tmport = base_io + 0x41;
  2525.    outb(8, tmport++);
  2526.    outb(0x7f, tmport);
  2527.    tmport = base_io + 0x51;
  2528.    outb(0x20, tmport);
  2529.    tscam(h);
  2530.    is880(h, base_io);
  2531.    tmport = base_io + 0x38;
  2532.    outb(0xb0, tmport);
  2533. }
  2534. atp_host[h] = shpnt;
  2535. if (dev->chip_veru == 4) {
  2536. shpnt->max_id = 16;
  2537. }
  2538. shpnt->this_id = host_id;
  2539. shpnt->unique_id = base_io;
  2540. shpnt->io_port = base_io;
  2541. if (dev_id[h] == 0x8081)
  2542. {
  2543.    shpnt->n_io_port = 0x60;    /* Number of bytes of I/O space used */
  2544. }
  2545. else
  2546. {
  2547.    shpnt->n_io_port = 0x40;    /* Number of bytes of I/O space used */
  2548. }
  2549. shpnt->irq = irq;
  2550. restore_flags(flags);
  2551. if (dev_id[h] == 0x8081)
  2552. {
  2553.    request_region(base_io, 0x60, "atp870u");       /* Register the IO ports that we use */
  2554. }
  2555. else
  2556. {
  2557.    request_region(base_io, 0x40, "atp870u");       /* Register the IO ports that we use */
  2558. }
  2559. count++;
  2560. index++;
  2561. continue;
  2562. unregister:
  2563. scsi_unregister(shpnt);
  2564. restore_flags(flags);
  2565. index++;
  2566. continue;
  2567. }
  2568. return count;
  2569. }
  2570. /* The abort command does not leave the device in a clean state where
  2571.    it is available to be used again.  Until this gets worked out, we will
  2572.    leave it commented out.  */
  2573. int atp870u_abort(Scsi_Cmnd * SCpnt)
  2574. {
  2575. unsigned char h, j, k;
  2576. Scsi_Cmnd *workrequ;
  2577. unsigned int tmport;
  2578. struct atp_unit *dev;
  2579. for (h = 0; h <= admaxu; h++) {
  2580. if (SCpnt->host == atp_host[h]) {
  2581. goto find_adp;
  2582. }
  2583. }
  2584. panic("Abort host not found !");
  2585. find_adp:
  2586. dev=&atp_unit[h];
  2587. printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd);
  2588. printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu);
  2589. tmport = dev->ioport;
  2590. for (j = 0; j < 0x17; j++) {
  2591. printk(" r%2x=%2x", j, inb(tmport++));
  2592. }
  2593. tmport += 0x05;
  2594. printk(" r1c=%2x", inb(tmport));
  2595. tmport += 0x03;
  2596. printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd);
  2597. tmport= dev->pciport;
  2598. printk(" r20=%2x", inb(tmport));
  2599. tmport += 0x02;
  2600. printk(" r22=%2x", inb(tmport));
  2601. tmport = dev->ioport + 0x3a;
  2602. printk(" r3a=%2x n",inb(tmport));
  2603. tmport = dev->ioport + 0x3b;
  2604. printk(" r3b=%2x n",inb(tmport));
  2605. for(j=0;j<16;j++)
  2606. {
  2607.    if (dev->id[j].curr_req != NULL)
  2608.    {
  2609. workrequ = dev->id[j].curr_req;
  2610. printk("n que cdb= ");
  2611. for (k=0; k < workrequ->cmd_len; k++)
  2612. {
  2613.     printk(" %2x ",workrequ->cmnd[k]);
  2614. }
  2615. printk(" last_lenu= %lx ",dev->id[j].last_lenu);
  2616.    }
  2617. }
  2618. return (SCSI_ABORT_SNOOZE);
  2619. }
  2620. int atp870u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
  2621. {
  2622. unsigned char h;
  2623. struct atp_unit *dev;
  2624. /*
  2625.  * See if a bus reset was suggested.
  2626.  */
  2627. for (h = 0; h <= admaxu; h++) {
  2628. if (SCpnt->host == atp_host[h]) {
  2629. goto find_host;
  2630. }
  2631. }
  2632. panic("Reset bus host not found !");
  2633. find_host:
  2634. dev=&atp_unit[h];
  2635. /* SCpnt->result = 0x00080000;
  2636. SCpnt->scsi_done(SCpnt);
  2637. dev->working=0;
  2638. dev->quhdu=0;
  2639. dev->quendu=0;
  2640. return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);  */
  2641. return (SCSI_RESET_SNOOZE);
  2642. }
  2643. const char *atp870u_info(struct Scsi_Host *notused)
  2644. {
  2645. static char buffer[128];
  2646. strcpy(buffer, "ACARD AEC-6710/6712/67160 PCI Ultra/W/LVD SCSI-3 Adapter Driver V2.5+ac ");
  2647. return buffer;
  2648. }
  2649. int atp870u_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
  2650. {
  2651. return -ENOSYS;  /* Currently this is a no-op */
  2652. }
  2653. #define BLS buffer + len + size
  2654. int atp870u_proc_info(char *buffer, char **start, off_t offset, int length,
  2655.       int hostno, int inout)
  2656. {
  2657. struct Scsi_Host *HBAptr;
  2658. static u8 buff[512];
  2659. int i;
  2660. int size = 0;
  2661. int len = 0;
  2662. off_t begin = 0;
  2663. off_t pos = 0;
  2664. HBAptr = NULL;
  2665. for (i = 0; i < 2; i++) {
  2666. if ((HBAptr = atp_host[i]) != NULL) {
  2667. if (HBAptr->host_no == hostno) {
  2668. break;
  2669. }
  2670. HBAptr = NULL;
  2671. }
  2672. }
  2673. if (HBAptr == NULL) {
  2674. size += sprintf(BLS, "Can't find adapter for host number %dn", hostno);
  2675. len += size;
  2676. pos = begin + len;
  2677. size = 0;
  2678. goto stop_output;
  2679. }
  2680. if (inout == TRUE) { /* Has data been written to the file? */
  2681. return (atp870u_set_info(buffer, length, HBAptr));
  2682. }
  2683. if (offset == 0) {
  2684. memset(buff, 0, sizeof(buff));
  2685. }
  2686. size += sprintf(BLS, "ACARD AEC-671X Driver Version: 2.5+acn");
  2687. len += size;
  2688. pos = begin + len;
  2689. size = 0;
  2690. size += sprintf(BLS, "n");
  2691. size += sprintf(BLS, "Adapter Configuration:n");
  2692. size += sprintf(BLS, "               Base IO: %#.4lxn", HBAptr->io_port);
  2693. size += sprintf(BLS, "                   IRQ: %dn", HBAptr->irq);
  2694. len += size;
  2695. pos = begin + len;
  2696. size = 0;
  2697. stop_output:
  2698. *start = buffer + (offset - begin); /* Start of wanted data */
  2699. len -= (offset - begin); /* Start slop */
  2700. if (len > length) {
  2701. len = length; /* Ending slop */
  2702. }
  2703. return (len);
  2704. }
  2705. #include "sd.h"
  2706. int atp870u_biosparam(Scsi_Disk * disk, kdev_t dev, int *ip)
  2707. {
  2708. int heads, sectors, cylinders;
  2709. heads = 64;
  2710. sectors = 32;
  2711. cylinders = disk->capacity / (heads * sectors);
  2712. if (cylinders > 1024) {
  2713. heads = 255;
  2714. sectors = 63;
  2715. cylinders = disk->capacity / (heads * sectors);
  2716. }
  2717. ip[0] = heads;
  2718. ip[1] = sectors;
  2719. ip[2] = cylinders;
  2720. return 0;
  2721. }
  2722. int atp870u_release (struct Scsi_Host *pshost)
  2723. {
  2724. int h;
  2725. for (h = 0; h <= admaxu; h++)
  2726. {
  2727. if (pshost == atp_host[h]) {
  2728. int k;
  2729. free_irq (pshost->irq, &atp_unit[h]);
  2730. release_region (pshost->io_port, pshost->n_io_port);
  2731. scsi_unregister(pshost);
  2732. for(k=0;k<16;k++)
  2733. kfree(atp_unit[h].id[k].prd_tableu);
  2734. return 0;
  2735. }
  2736. }
  2737. panic("atp870u: bad scsi host passed.n");
  2738. }
  2739. MODULE_LICENSE("GPL");
  2740. static Scsi_Host_Template driver_template = ATP870U;
  2741. #include "scsi_module.c"