aic7xxx_core.c
Upload User: jlfgdled
Upload Date: 2013-04-10
Package Size: 33168k
Code Size: 189k
Development Platform:

Unix_Linux

  1. #ifndef __FreeBSD__
  2. free(ahc, M_DEVBUF);
  3. #endif
  4. free(name, M_DEVBUF);
  5. return (NULL);
  6. }
  7. LIST_INIT(&ahc->pending_scbs);
  8. /* We don't know our unit number until the OSM sets it */
  9. ahc->name = name;
  10. ahc->unit = -1;
  11. ahc->description = NULL;
  12. ahc->channel = 'A';
  13. ahc->channel_b = 'B';
  14. ahc->chip = AHC_NONE;
  15. ahc->features = AHC_FENONE;
  16. ahc->bugs = AHC_BUGNONE;
  17. ahc->flags = AHC_FNONE;
  18. for (i = 0; i < AHC_NUM_TARGETS; i++)
  19. TAILQ_INIT(&ahc->untagged_queues[i]);
  20. if (ahc_platform_alloc(ahc, platform_arg) != 0) {
  21. ahc_free(ahc);
  22. ahc = NULL;
  23. }
  24. return (ahc);
  25. }
  26. int
  27. ahc_softc_init(struct ahc_softc *ahc)
  28. {
  29. /* The IRQMS bit is only valid on VL and EISA chips */
  30. if ((ahc->chip & AHC_PCI) == 0)
  31. ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
  32. else
  33. ahc->unpause = 0;
  34. ahc->pause = ahc->unpause | PAUSE; 
  35. /* XXX The shared scb data stuff should be deprecated */
  36. if (ahc->scb_data == NULL) {
  37. ahc->scb_data = malloc(sizeof(*ahc->scb_data),
  38.        M_DEVBUF, M_NOWAIT);
  39. if (ahc->scb_data == NULL)
  40. return (ENOMEM);
  41. memset(ahc->scb_data, 0, sizeof(*ahc->scb_data));
  42. }
  43. return (0);
  44. }
  45. void
  46. ahc_softc_insert(struct ahc_softc *ahc)
  47. {
  48. struct ahc_softc *list_ahc;
  49. #if AHC_PCI_CONFIG > 0
  50. /*
  51.  * Second Function PCI devices need to inherit some
  52.  * settings from function 0.
  53.  */
  54. if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
  55.  && (ahc->features & AHC_MULTI_FUNC) != 0) {
  56. TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
  57. ahc_dev_softc_t list_pci;
  58. ahc_dev_softc_t pci;
  59. list_pci = list_ahc->dev_softc;
  60. pci = ahc->dev_softc;
  61. if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
  62.  && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
  63. struct ahc_softc *master;
  64. struct ahc_softc *slave;
  65. if (ahc_get_pci_function(list_pci) == 0) {
  66. master = list_ahc;
  67. slave = ahc;
  68. } else {
  69. master = ahc;
  70. slave = list_ahc;
  71. }
  72. slave->flags &= ~AHC_BIOS_ENABLED; 
  73. slave->flags |=
  74.     master->flags & AHC_BIOS_ENABLED;
  75. slave->flags &= ~AHC_PRIMARY_CHANNEL; 
  76. slave->flags |=
  77.     master->flags & AHC_PRIMARY_CHANNEL;
  78. break;
  79. }
  80. }
  81. }
  82. #endif
  83. /*
  84.  * Insertion sort into our list of softcs.
  85.  */
  86. list_ahc = TAILQ_FIRST(&ahc_tailq);
  87. while (list_ahc != NULL
  88.     && ahc_softc_comp(list_ahc, ahc) <= 0)
  89. list_ahc = TAILQ_NEXT(list_ahc, links);
  90. if (list_ahc != NULL)
  91. TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
  92. else
  93. TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
  94. ahc->init_level++;
  95. }
  96. /*
  97.  * Verify that the passed in softc pointer is for a
  98.  * controller that is still configured.
  99.  */
  100. struct ahc_softc *
  101. ahc_find_softc(struct ahc_softc *ahc)
  102. {
  103. struct ahc_softc *list_ahc;
  104. TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
  105. if (list_ahc == ahc)
  106. return (ahc);
  107. }
  108. return (NULL);
  109. }
  110. void
  111. ahc_set_unit(struct ahc_softc *ahc, int unit)
  112. {
  113. ahc->unit = unit;
  114. }
  115. void
  116. ahc_set_name(struct ahc_softc *ahc, char *name)
  117. {
  118. if (ahc->name != NULL)
  119. free(ahc->name, M_DEVBUF);
  120. ahc->name = name;
  121. }
  122. void
  123. ahc_free(struct ahc_softc *ahc)
  124. {
  125. int i;
  126. ahc_fini_scbdata(ahc);
  127. switch (ahc->init_level) {
  128. default:
  129. case 5:
  130. ahc_shutdown(ahc);
  131. TAILQ_REMOVE(&ahc_tailq, ahc, links);
  132. /* FALLTHROUGH */
  133. case 4:
  134. ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
  135.   ahc->shared_data_dmamap);
  136. /* FALLTHROUGH */
  137. case 3:
  138. ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
  139. ahc->shared_data_dmamap);
  140. ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
  141.    ahc->shared_data_dmamap);
  142. /* FALLTHROUGH */
  143. case 2:
  144. ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
  145. case 1:
  146. #ifndef __linux__
  147. ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
  148. #endif
  149. break;
  150. case 0:
  151. break;
  152. }
  153. #ifndef __linux__
  154. ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
  155. #endif
  156. ahc_platform_free(ahc);
  157. for (i = 0; i < AHC_NUM_TARGETS; i++) {
  158. struct ahc_tmode_tstate *tstate;
  159. tstate = ahc->enabled_targets[i];
  160. if (tstate != NULL) {
  161. #if AHC_TARGET_MODE
  162. int j;
  163. for (j = 0; j < AHC_NUM_LUNS; j++) {
  164. struct ahc_tmode_lstate *lstate;
  165. lstate = tstate->enabled_luns[j];
  166. if (lstate != NULL) {
  167. xpt_free_path(lstate->path);
  168. free(lstate, M_DEVBUF);
  169. }
  170. }
  171. #endif
  172. free(tstate, M_DEVBUF);
  173. }
  174. }
  175. #if AHC_TARGET_MODE
  176. if (ahc->black_hole != NULL) {
  177. xpt_free_path(ahc->black_hole->path);
  178. free(ahc->black_hole, M_DEVBUF);
  179. }
  180. #endif
  181. if (ahc->name != NULL)
  182. free(ahc->name, M_DEVBUF);
  183. if (ahc->seep_config != NULL)
  184. free(ahc->seep_config, M_DEVBUF);
  185. #ifndef __FreeBSD__
  186. free(ahc, M_DEVBUF);
  187. #endif
  188. return;
  189. }
  190. void
  191. ahc_shutdown(void *arg)
  192. {
  193. struct ahc_softc *ahc;
  194. int i;
  195. ahc = (struct ahc_softc *)arg;
  196. /* This will reset most registers to 0, but not all */
  197. ahc_reset(ahc);
  198. ahc_outb(ahc, SCSISEQ, 0);
  199. ahc_outb(ahc, SXFRCTL0, 0);
  200. ahc_outb(ahc, DSPCISTATUS, 0);
  201. for (i = TARG_SCSIRATE; i < SCSICONF; i++)
  202. ahc_outb(ahc, i, 0);
  203. }
  204. /*
  205.  * Reset the controller and record some information about it
  206.  * that is only available just after a reset.
  207.  */
  208. int
  209. ahc_reset(struct ahc_softc *ahc)
  210. {
  211. u_int sblkctl;
  212. u_int sxfrctl1_a, sxfrctl1_b;
  213. int wait;
  214. /*
  215.  * Preserve the value of the SXFRCTL1 register for all channels.
  216.  * It contains settings that affect termination and we don't want
  217.  * to disturb the integrity of the bus.
  218.  */
  219. ahc_pause(ahc);
  220. sxfrctl1_b = 0;
  221. if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
  222. u_int sblkctl;
  223. /*
  224.  * Save channel B's settings in case this chip
  225.  * is setup for TWIN channel operation.
  226.  */
  227. sblkctl = ahc_inb(ahc, SBLKCTL);
  228. ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
  229. sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
  230. ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
  231. }
  232. sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
  233. ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
  234. /*
  235.  * Ensure that the reset has finished.  We delay 1000us
  236.  * prior to reading the register to make sure the chip
  237.  * has sufficiently completed its reset to handle register
  238.  * accesses.
  239.  */
  240. wait = 1000;
  241. do {
  242. ahc_delay(1000);
  243. } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
  244. if (wait == 0) {
  245. printf("%s: WARNING - Failed chip reset!  "
  246.        "Trying to initialize anyway.n", ahc_name(ahc));
  247. }
  248. ahc_outb(ahc, HCNTRL, ahc->pause);
  249. /* Determine channel configuration */
  250. sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
  251. /* No Twin Channel PCI cards */
  252. if ((ahc->chip & AHC_PCI) != 0)
  253. sblkctl &= ~SELBUSB;
  254. switch (sblkctl) {
  255. case 0:
  256. /* Single Narrow Channel */
  257. break;
  258. case 2:
  259. /* Wide Channel */
  260. ahc->features |= AHC_WIDE;
  261. break;
  262. case 8:
  263. /* Twin Channel */
  264. ahc->features |= AHC_TWIN;
  265. break;
  266. default:
  267. printf(" Unsupported adapter type.  Ignoringn");
  268. return(-1);
  269. }
  270. /*
  271.  * Reload sxfrctl1.
  272.  *
  273.  * We must always initialize STPWEN to 1 before we
  274.  * restore the saved values.  STPWEN is initialized
  275.  * to a tri-state condition which can only be cleared
  276.  * by turning it on.
  277.  */
  278. if ((ahc->features & AHC_TWIN) != 0) {
  279. u_int sblkctl;
  280. sblkctl = ahc_inb(ahc, SBLKCTL);
  281. ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
  282. ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
  283. ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
  284. }
  285. ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
  286. #ifdef AHC_DUMP_SEQ
  287. if (ahc->init_level == 0)
  288. ahc_dumpseq(ahc);
  289. #endif
  290. return (0);
  291. }
  292. /*
  293.  * Determine the number of SCBs available on the controller
  294.  */
  295. int
  296. ahc_probe_scbs(struct ahc_softc *ahc) {
  297. int i;
  298. for (i = 0; i < AHC_SCB_MAX; i++) {
  299. ahc_outb(ahc, SCBPTR, i);
  300. ahc_outb(ahc, SCB_BASE, i);
  301. if (ahc_inb(ahc, SCB_BASE) != i)
  302. break;
  303. ahc_outb(ahc, SCBPTR, 0);
  304. if (ahc_inb(ahc, SCB_BASE) != 0)
  305. break;
  306. }
  307. return (i);
  308. }
  309. static void
  310. ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) 
  311. {
  312. bus_addr_t *baddr;
  313. baddr = (bus_addr_t *)arg;
  314. *baddr = segs->ds_addr;
  315. }
  316. static void
  317. ahc_build_free_scb_list(struct ahc_softc *ahc)
  318. {
  319. int scbsize;
  320. int i;
  321. scbsize = 32;
  322. if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
  323. scbsize = 64;
  324. for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
  325. int j;
  326. ahc_outb(ahc, SCBPTR, i);
  327. /*
  328.  * Touch all SCB bytes to avoid parity errors
  329.  * should one of our debugging routines read
  330.  * an otherwise uninitiatlized byte.
  331.  */
  332. for (j = 0; j < scbsize; j++)
  333. ahc_outb(ahc, SCB_BASE+j, 0xFF);
  334. /* Clear the control byte. */
  335. ahc_outb(ahc, SCB_CONTROL, 0);
  336. /* Set the next pointer */
  337. if ((ahc->flags & AHC_PAGESCBS) != 0)
  338. ahc_outb(ahc, SCB_NEXT, i+1);
  339. else 
  340. ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
  341. /* Make the tag number, SCSIID, and lun invalid */
  342. ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
  343. ahc_outb(ahc, SCB_SCSIID, 0xFF);
  344. ahc_outb(ahc, SCB_LUN, 0xFF);
  345. }
  346. /* Make sure that the last SCB terminates the free list */
  347. ahc_outb(ahc, SCBPTR, i-1);
  348. ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
  349. }
  350. static int
  351. ahc_init_scbdata(struct ahc_softc *ahc)
  352. {
  353. struct scb_data *scb_data;
  354. scb_data = ahc->scb_data;
  355. SLIST_INIT(&scb_data->free_scbs);
  356. SLIST_INIT(&scb_data->sg_maps);
  357. /* Allocate SCB resources */
  358. scb_data->scbarray =
  359.     (struct scb *)malloc(sizeof(struct scb) * AHC_SCB_MAX_ALLOC,
  360.  M_DEVBUF, M_NOWAIT);
  361. if (scb_data->scbarray == NULL)
  362. return (ENOMEM);
  363. memset(scb_data->scbarray, 0, sizeof(struct scb) * AHC_SCB_MAX_ALLOC);
  364. /* Determine the number of hardware SCBs and initialize them */
  365. scb_data->maxhscbs = ahc_probe_scbs(ahc);
  366. if ((ahc->flags & AHC_PAGESCBS) != 0) {
  367. /* SCB 0 heads the free list */
  368. ahc_outb(ahc, FREE_SCBH, 0);
  369. } else {
  370. ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
  371. }
  372. if (ahc->scb_data->maxhscbs == 0) {
  373. printf("%s: No SCB space foundn", ahc_name(ahc));
  374. return (ENXIO);
  375. }
  376. ahc_build_free_scb_list(ahc);
  377. /*
  378.  * Create our DMA tags.  These tags define the kinds of device
  379.  * accessible memory allocations and memory mappings we will
  380.  * need to perform during normal operation.
  381.  *
  382.  * Unless we need to further restrict the allocation, we rely
  383.  * on the restrictions of the parent dmat, hence the common
  384.  * use of MAXADDR and MAXSIZE.
  385.  */
  386. /* DMA tag for our hardware scb structures */
  387. if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
  388.        /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
  389.        /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  390.        /*highaddr*/BUS_SPACE_MAXADDR,
  391.        /*filter*/NULL, /*filterarg*/NULL,
  392.        AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
  393.        /*nsegments*/1,
  394.        /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  395.        /*flags*/0, &scb_data->hscb_dmat) != 0) {
  396. goto error_exit;
  397. }
  398. scb_data->init_level++;
  399. /* Allocation for our hscbs */
  400. if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
  401.      (void **)&scb_data->hscbs,
  402.      BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
  403. goto error_exit;
  404. }
  405. scb_data->init_level++;
  406. /* And permanently map them */
  407. ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
  408. scb_data->hscbs,
  409. AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
  410. ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);
  411. scb_data->init_level++;
  412. /* DMA tag for our sense buffers */
  413. if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
  414.        /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
  415.        /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  416.        /*highaddr*/BUS_SPACE_MAXADDR,
  417.        /*filter*/NULL, /*filterarg*/NULL,
  418.        AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
  419.        /*nsegments*/1,
  420.        /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  421.        /*flags*/0, &scb_data->sense_dmat) != 0) {
  422. goto error_exit;
  423. }
  424. scb_data->init_level++;
  425. /* Allocate them */
  426. if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
  427.      (void **)&scb_data->sense,
  428.      BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
  429. goto error_exit;
  430. }
  431. scb_data->init_level++;
  432. /* And permanently map them */
  433. ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
  434. scb_data->sense,
  435. AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
  436. ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);
  437. scb_data->init_level++;
  438. /* DMA tag for our S/G structures.  We allocate in page sized chunks */
  439. if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
  440.        /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
  441.        /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  442.        /*highaddr*/BUS_SPACE_MAXADDR,
  443.        /*filter*/NULL, /*filterarg*/NULL,
  444.        PAGE_SIZE, /*nsegments*/1,
  445.        /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  446.        /*flags*/0, &scb_data->sg_dmat) != 0) {
  447. goto error_exit;
  448. }
  449. scb_data->init_level++;
  450. /* Perform initial CCB allocation */
  451. memset(scb_data->hscbs, 0,
  452.        AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
  453. ahc_alloc_scbs(ahc);
  454. if (scb_data->numscbs == 0) {
  455. printf("%s: ahc_init_scbdata - "
  456.        "Unable to allocate initial scbsn",
  457.        ahc_name(ahc));
  458. goto error_exit;
  459. }
  460. /*
  461.  * Tell the sequencer which SCB will be the next one it receives.
  462.  */
  463. ahc->next_queued_scb = ahc_get_scb(ahc);
  464. ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
  465. /*
  466.  * Note that we were successfull
  467.  */
  468. return (0); 
  469. error_exit:
  470. return (ENOMEM);
  471. }
  472. static void
  473. ahc_fini_scbdata(struct ahc_softc *ahc)
  474. {
  475. struct scb_data *scb_data;
  476. scb_data = ahc->scb_data;
  477. if (scb_data == NULL)
  478. return;
  479. switch (scb_data->init_level) {
  480. default:
  481. case 7:
  482. {
  483. struct sg_map_node *sg_map;
  484. while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
  485. SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
  486. ahc_dmamap_unload(ahc, scb_data->sg_dmat,
  487.   sg_map->sg_dmamap);
  488. ahc_dmamem_free(ahc, scb_data->sg_dmat,
  489. sg_map->sg_vaddr,
  490. sg_map->sg_dmamap);
  491. free(sg_map, M_DEVBUF);
  492. }
  493. ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
  494. }
  495. case 6:
  496. ahc_dmamap_unload(ahc, scb_data->sense_dmat,
  497.   scb_data->sense_dmamap);
  498. case 5:
  499. ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
  500. scb_data->sense_dmamap);
  501. ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
  502.    scb_data->sense_dmamap);
  503. case 4:
  504. ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
  505. case 3:
  506. ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
  507.   scb_data->hscb_dmamap);
  508. case 2:
  509. ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
  510. scb_data->hscb_dmamap);
  511. ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
  512.    scb_data->hscb_dmamap);
  513. case 1:
  514. ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
  515. break;
  516. case 0:
  517. break;
  518. }
  519. if (scb_data->scbarray != NULL)
  520. free(scb_data->scbarray, M_DEVBUF);
  521. }
  522. void
  523. ahc_alloc_scbs(struct ahc_softc *ahc)
  524. {
  525. struct scb_data *scb_data;
  526. struct scb *next_scb;
  527. struct sg_map_node *sg_map;
  528. bus_addr_t physaddr;
  529. struct ahc_dma_seg *segs;
  530. int newcount;
  531. int i;
  532. scb_data = ahc->scb_data;
  533. if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
  534. /* Can't allocate any more */
  535. return;
  536. next_scb = &scb_data->scbarray[scb_data->numscbs];
  537. sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
  538. if (sg_map == NULL)
  539. return;
  540. /* Allocate S/G space for the next batch of SCBS */
  541. if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
  542.      (void **)&sg_map->sg_vaddr,
  543.      BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
  544. free(sg_map, M_DEVBUF);
  545. return;
  546. }
  547. SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
  548. ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
  549. sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
  550. &sg_map->sg_physaddr, /*flags*/0);
  551. segs = sg_map->sg_vaddr;
  552. physaddr = sg_map->sg_physaddr;
  553. newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
  554. newcount = MIN(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
  555. for (i = 0; i < newcount; i++) {
  556. struct scb_platform_data *pdata;
  557. #ifndef __linux__
  558. int error;
  559. #endif
  560. pdata = (struct scb_platform_data *)malloc(sizeof(*pdata),
  561.    M_DEVBUF, M_NOWAIT);
  562. if (pdata == NULL)
  563. break;
  564. next_scb->platform_data = pdata;
  565. next_scb->sg_map = sg_map;
  566. next_scb->sg_list = segs;
  567. /*
  568.  * The sequencer always starts with the second entry.
  569.  * The first entry is embedded in the scb.
  570.  */
  571. next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
  572. next_scb->ahc_softc = ahc;
  573. next_scb->flags = SCB_FREE;
  574. #ifndef __linux__
  575. error = ahc_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
  576.   &next_scb->dmamap);
  577. if (error != 0)
  578. break;
  579. #endif
  580. next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
  581. next_scb->hscb->tag = ahc->scb_data->numscbs;
  582. SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
  583.   next_scb, links.sle);
  584. segs += AHC_NSEG;
  585. physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
  586. next_scb++;
  587. ahc->scb_data->numscbs++;
  588. }
  589. }
  590. void
  591. ahc_controller_info(struct ahc_softc *ahc, char *buf)
  592. {
  593. int len;
  594. len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
  595. buf += len;
  596. if ((ahc->features & AHC_TWIN) != 0)
  597.   len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
  598.       "B SCSI Id=%d, primary %c, ",
  599.       ahc->our_id, ahc->our_id_b,
  600.       (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
  601. else {
  602. const char *speed;
  603. const char *type;
  604. speed = "";
  605. if ((ahc->features & AHC_ULTRA) != 0) {
  606. speed = "Ultra ";
  607. } else if ((ahc->features & AHC_DT) != 0) {
  608. speed = "Ultra160 ";
  609. } else if ((ahc->features & AHC_ULTRA2) != 0) {
  610. speed = "Ultra2 ";
  611. }
  612. if ((ahc->features & AHC_WIDE) != 0) {
  613. type = "Wide";
  614. } else {
  615. type = "Single";
  616. }
  617. len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
  618.       speed, type, ahc->channel, ahc->our_id);
  619. }
  620. buf += len;
  621. if ((ahc->flags & AHC_PAGESCBS) != 0)
  622. sprintf(buf, "%d/%d SCBs",
  623. ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
  624. else
  625. sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
  626. }
  627. /*
  628.  * Start the board, ready for normal operation
  629.  */
  630. int
  631. ahc_init(struct ahc_softc *ahc)
  632. {
  633. int  max_targ;
  634. int  i;
  635. int  term;
  636. u_int  scsi_conf;
  637. u_int  scsiseq_template;
  638. u_int  ultraenb;
  639. u_int  discenable;
  640. u_int  tagenable;
  641. size_t  driver_data_size;
  642. uint32_t physaddr;
  643. #ifdef AHC_DEBUG_SEQUENCER
  644. ahc->flags |= AHC_SEQUENCER_DEBUG;
  645. #endif
  646. #ifdef AHC_PRINT_SRAM
  647. printf("Scratch Ram:");
  648. for (i = 0x20; i < 0x5f; i++) {
  649. if (((i % 8) == 0) && (i != 0)) {
  650. printf ("n              ");
  651. }
  652. printf (" 0x%x", ahc_inb(ahc, i));
  653. }
  654. if ((ahc->features & AHC_MORE_SRAM) != 0) {
  655. for (i = 0x70; i < 0x7f; i++) {
  656. if (((i % 8) == 0) && (i != 0)) {
  657. printf ("n              ");
  658. }
  659. printf (" 0x%x", ahc_inb(ahc, i));
  660. }
  661. }
  662. printf ("n");
  663. /*
  664.  * Reading uninitialized scratch ram may
  665.  * generate parity errors.
  666.  */
  667. ahc_outb(ahc, CLRINT, CLRPARERR);
  668. ahc_outb(ahc, CLRINT, CLRBRKADRINT);
  669. #endif
  670. max_targ = 15;
  671. /*
  672.  * Assume we have a board at this stage and it has been reset.
  673.  */
  674. if ((ahc->flags & AHC_USEDEFAULTS) != 0)
  675. ahc->our_id = ahc->our_id_b = 7;
  676. /*
  677.  * Default to allowing initiator operations.
  678.  */
  679. ahc->flags |= AHC_INITIATORROLE;
  680. /*
  681.  * Only allow target mode features if this unit has them enabled.
  682.  */
  683. if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
  684. ahc->features &= ~AHC_TARGETMODE;
  685. #ifndef __linux__
  686. /* DMA tag for mapping buffers into device visible space. */
  687. if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
  688.        /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
  689.        /*lowaddr*/BUS_SPACE_MAXADDR,
  690.        /*highaddr*/BUS_SPACE_MAXADDR,
  691.        /*filter*/NULL, /*filterarg*/NULL,
  692.        /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG,
  693.        /*maxsegsz*/AHC_MAXTRANSFER_SIZE,
  694.        /*flags*/BUS_DMA_ALLOCNOW,
  695.        &ahc->buffer_dmat) != 0) {
  696. return (ENOMEM);
  697. }
  698. #endif
  699. ahc->init_level++;
  700. /*
  701.  * DMA tag for our command fifos and other data in system memory
  702.  * the card's sequencer must be able to access.  For initiator
  703.  * roles, we need to allocate space for the qinfifo and qoutfifo.
  704.  * The qinfifo and qoutfifo are composed of 256 1 byte elements. 
  705.  * When providing for the target mode role, we must additionally
  706.  * provide space for the incoming target command fifo and an extra
  707.  * byte to deal with a dma bug in some chip versions.
  708.  */
  709. driver_data_size = 2 * 256 * sizeof(uint8_t);
  710. if ((ahc->features & AHC_TARGETMODE) != 0)
  711. driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
  712.  + /*DMA WideOdd Bug Buffer*/1;
  713. if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
  714.        /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
  715.        /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  716.        /*highaddr*/BUS_SPACE_MAXADDR,
  717.        /*filter*/NULL, /*filterarg*/NULL,
  718.        driver_data_size,
  719.        /*nsegments*/1,
  720.        /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  721.        /*flags*/0, &ahc->shared_data_dmat) != 0) {
  722. return (ENOMEM);
  723. }
  724. ahc->init_level++;
  725. /* Allocation of driver data */
  726. if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
  727.      (void **)&ahc->qoutfifo,
  728.      BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
  729. return (ENOMEM);
  730. }
  731. ahc->init_level++;
  732. /* And permanently map it in */
  733. ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
  734. ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
  735. &ahc->shared_data_busaddr, /*flags*/0);
  736. if ((ahc->features & AHC_TARGETMODE) != 0) {
  737. ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
  738. ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
  739. ahc->dma_bug_buf = ahc->shared_data_busaddr
  740.  + driver_data_size - 1;
  741. /* All target command blocks start out invalid. */
  742. for (i = 0; i < AHC_TMODE_CMDS; i++)
  743. ahc->targetcmds[i].cmd_valid = 0;
  744. ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
  745. ahc->tqinfifonext = 1;
  746. ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
  747. ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
  748. ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
  749. }
  750. ahc->qinfifo = &ahc->qoutfifo[256];
  751. ahc->init_level++;
  752. /* Allocate SCB data now that buffer_dmat is initialized */
  753. if (ahc->scb_data->maxhscbs == 0)
  754. if (ahc_init_scbdata(ahc) != 0)
  755. return (ENOMEM);
  756. /*
  757.  * Allocate a tstate to house information for our
  758.  * initiator presence on the bus as well as the user
  759.  * data for any target mode initiator.
  760.  */
  761. if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
  762. printf("%s: unable to allocate ahc_tmode_tstate.  "
  763.        "Failing attachn", ahc_name(ahc));
  764. return (ENOMEM);
  765. }
  766. if ((ahc->features & AHC_TWIN) != 0) {
  767. if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
  768. printf("%s: unable to allocate ahc_tmode_tstate.  "
  769.        "Failing attachn", ahc_name(ahc));
  770. return (ENOMEM);
  771. }
  772. }
  773. ahc_outb(ahc, SEQ_FLAGS, 0);
  774. ahc_outb(ahc, SEQ_FLAGS2, 0);
  775. if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
  776. ahc->flags |= AHC_PAGESCBS;
  777. } else {
  778. ahc->flags &= ~AHC_PAGESCBS;
  779. }
  780. #ifdef AHC_DEBUG
  781. if (ahc_debug & AHC_SHOWMISC) {
  782. printf("%s: hardware scb %d bytes; kernel scb %d bytes; "
  783.        "ahc_dma %d bytesn",
  784. ahc_name(ahc),
  785. sizeof(struct hardware_scb),
  786. sizeof(struct scb),
  787. sizeof(struct ahc_dma_seg));
  788. }
  789. #endif /* AHC_DEBUG */
  790. /* Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels*/
  791. if (ahc->features & AHC_TWIN) {
  792. /*
  793.  * The device is gated to channel B after a chip reset,
  794.  * so set those values first
  795.  */
  796. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
  797. term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
  798. ahc_outb(ahc, SCSIID, ahc->our_id_b);
  799. scsi_conf = ahc_inb(ahc, SCSICONF + 1);
  800. ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
  801. |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
  802. if ((ahc->features & AHC_ULTRA2) != 0)
  803. ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
  804. ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
  805. ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
  806. if ((scsi_conf & RESET_SCSI) != 0
  807.  && (ahc->flags & AHC_INITIATORROLE) != 0)
  808. ahc->flags |= AHC_RESET_BUS_B;
  809. /* Select Channel A */
  810. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
  811. }
  812. term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
  813. if ((ahc->features & AHC_ULTRA2) != 0)
  814. ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
  815. else
  816. ahc_outb(ahc, SCSIID, ahc->our_id);
  817. scsi_conf = ahc_inb(ahc, SCSICONF);
  818. ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
  819. |term|ahc->seltime
  820. |ENSTIMER|ACTNEGEN);
  821. if ((ahc->features & AHC_ULTRA2) != 0)
  822. ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
  823. ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
  824. ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
  825. if ((scsi_conf & RESET_SCSI) != 0
  826.  && (ahc->flags & AHC_INITIATORROLE) != 0)
  827. ahc->flags |= AHC_RESET_BUS_A;
  828. /*
  829.  * Look at the information that board initialization or
  830.  * the board bios has left us.
  831.  */
  832. ultraenb = 0;
  833. tagenable = ALL_TARGETS_MASK;
  834. /* Grab the disconnection disable table and invert it for our needs */
  835. if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
  836. printf("%s: Host Adapter Bios disabled.  Using default SCSI "
  837. "device parametersn", ahc_name(ahc));
  838. ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
  839.       AHC_TERM_ENB_A|AHC_TERM_ENB_B;
  840. discenable = ALL_TARGETS_MASK;
  841. if ((ahc->features & AHC_ULTRA) != 0)
  842. ultraenb = ALL_TARGETS_MASK;
  843. } else {
  844. discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
  845.    | ahc_inb(ahc, DISC_DSB));
  846. if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
  847. ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
  848.       | ahc_inb(ahc, ULTRA_ENB);
  849. }
  850. if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
  851. max_targ = 7;
  852. for (i = 0; i <= max_targ; i++) {
  853. struct ahc_initiator_tinfo *tinfo;
  854. struct ahc_tmode_tstate *tstate;
  855. u_int our_id;
  856. u_int target_id;
  857. char channel;
  858. channel = 'A';
  859. our_id = ahc->our_id;
  860. target_id = i;
  861. if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
  862. channel = 'B';
  863. our_id = ahc->our_id_b;
  864. target_id = i % 8;
  865. }
  866. tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
  867.     target_id, &tstate);
  868. /* Default to async narrow across the board */
  869. memset(tinfo, 0, sizeof(*tinfo));
  870. if (ahc->flags & AHC_USEDEFAULTS) {
  871. if ((ahc->features & AHC_WIDE) != 0)
  872. tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
  873. /*
  874.  * These will be truncated when we determine the
  875.  * connection type we have with the target.
  876.  */
  877. tinfo->user.period = ahc_syncrates->period;
  878. tinfo->user.offset = ~0;
  879. } else {
  880. u_int scsirate;
  881. uint16_t mask;
  882. /* Take the settings leftover in scratch RAM. */
  883. scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
  884. mask = (0x01 << i);
  885. if ((ahc->features & AHC_ULTRA2) != 0) {
  886. u_int offset;
  887. u_int maxsync;
  888. if ((scsirate & SOFS) == 0x0F) {
  889. /*
  890.  * Haven't negotiated yet,
  891.  * so the format is different.
  892.  */
  893. scsirate = (scsirate & SXFR) >> 4
  894.  | (ultraenb & mask)
  895.   ? 0x08 : 0x0
  896.  | (scsirate & WIDEXFER);
  897. offset = MAX_OFFSET_ULTRA2;
  898. } else
  899. offset = ahc_inb(ahc, TARG_OFFSET + i);
  900. if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
  901. /* Set to the lowest sync rate, 5MHz */
  902. scsirate |= 0x1c;
  903. maxsync = AHC_SYNCRATE_ULTRA2;
  904. if ((ahc->features & AHC_DT) != 0)
  905. maxsync = AHC_SYNCRATE_DT;
  906. tinfo->user.period =
  907.     ahc_find_period(ahc, scsirate, maxsync);
  908. if (offset == 0)
  909. tinfo->user.period = 0;
  910. else
  911. tinfo->user.offset = ~0;
  912. if ((scsirate & SXFR_ULTRA2) <= 8/*10MHz*/
  913.  && (ahc->features & AHC_DT) != 0)
  914. tinfo->user.ppr_options =
  915.     MSG_EXT_PPR_DT_REQ;
  916. } else if ((scsirate & SOFS) != 0) {
  917. if ((scsirate & SXFR) == 0x40
  918.  && (ultraenb & mask) != 0) {
  919. /* Treat 10MHz as a non-ultra speed */
  920. scsirate &= ~SXFR;
  921.   ultraenb &= ~mask;
  922. }
  923. tinfo->user.period = 
  924.     ahc_find_period(ahc, scsirate,
  925.     (ultraenb & mask)
  926.    ? AHC_SYNCRATE_ULTRA
  927.    : AHC_SYNCRATE_FAST);
  928. if (tinfo->user.period != 0)
  929. tinfo->user.offset = ~0;
  930. }
  931. if (tinfo->user.period == 0)
  932. tinfo->user.offset = 0;
  933. if ((scsirate & WIDEXFER) != 0
  934.  && (ahc->features & AHC_WIDE) != 0)
  935. tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
  936. tinfo->user.protocol_version = 4;
  937. if ((ahc->features & AHC_DT) != 0)
  938. tinfo->user.transport_version = 3;
  939. else
  940. tinfo->user.transport_version = 2;
  941. tinfo->goal.protocol_version = 2;
  942. tinfo->goal.transport_version = 2;
  943. tinfo->curr.protocol_version = 2;
  944. tinfo->curr.transport_version = 2;
  945. }
  946. tstate->ultraenb = ultraenb;
  947. }
  948. ahc->user_discenable = discenable;
  949. ahc->user_tagenable = tagenable;
  950. /* There are no untagged SCBs active yet. */
  951. for (i = 0; i < 16; i++) {
  952. ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
  953. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  954. int lun;
  955. /*
  956.  * The SCB based BTT allows an entry per
  957.  * target and lun pair.
  958.  */
  959. for (lun = 1; lun < AHC_NUM_LUNS; lun++)
  960. ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
  961. }
  962. }
  963. /* All of our queues are empty */
  964. for (i = 0; i < 256; i++)
  965. ahc->qoutfifo[i] = SCB_LIST_NULL;
  966. ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
  967. for (i = 0; i < 256; i++)
  968. ahc->qinfifo[i] = SCB_LIST_NULL;
  969. if ((ahc->features & AHC_MULTI_TID) != 0) {
  970. ahc_outb(ahc, TARGID, 0);
  971. ahc_outb(ahc, TARGID + 1, 0);
  972. }
  973. /*
  974.  * Tell the sequencer where it can find our arrays in memory.
  975.  */
  976. physaddr = ahc->scb_data->hscb_busaddr;
  977. ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
  978. ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
  979. ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
  980. ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
  981. physaddr = ahc->shared_data_busaddr;
  982. ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
  983. ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
  984. ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
  985. ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
  986. /*
  987.  * Initialize the group code to command length table.
  988.  * This overrides the values in TARG_SCSIRATE, so only
  989.  * setup the table after we have processed that information.
  990.  */
  991. ahc_outb(ahc, CMDSIZE_TABLE, 5);
  992. ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
  993. ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
  994. ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
  995. ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
  996. ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
  997. ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
  998. ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
  999. /* Tell the sequencer of our initial queue positions */
  1000. ahc_outb(ahc, KERNEL_QINPOS, 0);
  1001. ahc_outb(ahc, QINPOS, 0);
  1002. ahc_outb(ahc, QOUTPOS, 0);
  1003. /*
  1004.  * Use the built in queue management registers
  1005.  * if they are available.
  1006.  */
  1007. if ((ahc->features & AHC_QUEUE_REGS) != 0) {
  1008. ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
  1009. ahc_outb(ahc, SDSCB_QOFF, 0);
  1010. ahc_outb(ahc, SNSCB_QOFF, 0);
  1011. ahc_outb(ahc, HNSCB_QOFF, 0);
  1012. }
  1013. /* We don't have any waiting selections */
  1014. ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
  1015. /* Our disconnection list is empty too */
  1016. ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
  1017. /* Message out buffer starts empty */
  1018. ahc_outb(ahc, MSG_OUT, MSG_NOOP);
  1019. /*
  1020.  * Setup the allowed SCSI Sequences based on operational mode.
  1021.  * If we are a target, we'll enalbe select in operations once
  1022.  * we've had a lun enabled.
  1023.  */
  1024. scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
  1025. if ((ahc->flags & AHC_INITIATORROLE) != 0)
  1026. scsiseq_template |= ENRSELI;
  1027. ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
  1028. /*
  1029.  * Load the Sequencer program and Enable the adapter
  1030.  * in "fast" mode.
  1031.  */
  1032. if (bootverbose)
  1033. printf("%s: Downloading Sequencer Program...",
  1034.        ahc_name(ahc));
  1035. ahc_loadseq(ahc);
  1036. if ((ahc->features & AHC_ULTRA2) != 0) {
  1037. int wait;
  1038. /*
  1039.  * Wait for up to 500ms for our transceivers
  1040.  * to settle.  If the adapter does not have
  1041.  * a cable attached, the tranceivers may
  1042.  * never settle, so don't complain if we
  1043.  * fail here.
  1044.  */
  1045. ahc_pause(ahc);
  1046. for (wait = 5000;
  1047.      (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
  1048.      wait--)
  1049. ahc_delay(100);
  1050. ahc_unpause(ahc);
  1051. }
  1052. return (0);
  1053. }
  1054. void
  1055. ahc_intr_enable(struct ahc_softc *ahc, int enable)
  1056. {
  1057. u_int hcntrl;
  1058. hcntrl = ahc_inb(ahc, HCNTRL);
  1059. hcntrl &= ~INTEN;
  1060. ahc->pause &= ~INTEN;
  1061. ahc->unpause &= ~INTEN;
  1062. if (enable) {
  1063. hcntrl |= INTEN;
  1064. ahc->pause |= INTEN;
  1065. ahc->unpause |= INTEN;
  1066. }
  1067. ahc_outb(ahc, HCNTRL, hcntrl);
  1068. }
  1069. /*
  1070.  * Ensure that the card is paused in a location
  1071.  * outside of all critical sections and that all
  1072.  * pending work is completed prior to returning.
  1073.  * This routine should only be called from outside
  1074.  * an interrupt context.
  1075.  */
  1076. void
  1077. ahc_pause_and_flushwork(struct ahc_softc *ahc)
  1078. {
  1079. int intstat;
  1080. int maxloops;
  1081. maxloops = 1000;
  1082. ahc->flags |= AHC_ALL_INTERRUPTS;
  1083. intstat = 0;
  1084. do {
  1085. ahc_intr(ahc);
  1086. ahc_pause(ahc);
  1087. ahc_clear_critical_section(ahc);
  1088. if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0)
  1089. break;
  1090. maxloops--;
  1091. } while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops);
  1092. if (maxloops == 0) {
  1093. printf("Infinite interrupt loop, INTSTAT = %x",
  1094.       ahc_inb(ahc, INTSTAT));
  1095. }
  1096. ahc_platform_flushwork(ahc);
  1097. ahc->flags &= ~AHC_ALL_INTERRUPTS;
  1098. }
  1099. int
  1100. ahc_suspend(struct ahc_softc *ahc)
  1101. {
  1102. uint8_t *ptr;
  1103. int  i;
  1104. ahc_pause_and_flushwork(ahc);
  1105. if (LIST_FIRST(&ahc->pending_scbs) != NULL)
  1106. return (EBUSY);
  1107. #if AHC_TARGET_MODE
  1108. /*
  1109.  * XXX What about ATIOs that have not yet been serviced?
  1110.  * Perhaps we should just refuse to be suspended if we
  1111.  * are acting in a target role.
  1112.  */
  1113. if (ahc->pending_device != NULL)
  1114. return (EBUSY);
  1115. #endif
  1116. /* Save volatile registers */
  1117. if ((ahc->features & AHC_TWIN) != 0) {
  1118. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
  1119. ahc->suspend_state.channel[1].scsiseq = ahc_inb(ahc, SCSISEQ);
  1120. ahc->suspend_state.channel[1].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
  1121. ahc->suspend_state.channel[1].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
  1122. ahc->suspend_state.channel[1].simode0 = ahc_inb(ahc, SIMODE0);
  1123. ahc->suspend_state.channel[1].simode1 = ahc_inb(ahc, SIMODE1);
  1124. ahc->suspend_state.channel[1].seltimer = ahc_inb(ahc, SELTIMER);
  1125. ahc->suspend_state.channel[1].seqctl = ahc_inb(ahc, SEQCTL);
  1126. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
  1127. }
  1128. ahc->suspend_state.channel[0].scsiseq = ahc_inb(ahc, SCSISEQ);
  1129. ahc->suspend_state.channel[0].sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
  1130. ahc->suspend_state.channel[0].sxfrctl1 = ahc_inb(ahc, SXFRCTL1);
  1131. ahc->suspend_state.channel[0].simode0 = ahc_inb(ahc, SIMODE0);
  1132. ahc->suspend_state.channel[0].simode1 = ahc_inb(ahc, SIMODE1);
  1133. ahc->suspend_state.channel[0].seltimer = ahc_inb(ahc, SELTIMER);
  1134. ahc->suspend_state.channel[0].seqctl = ahc_inb(ahc, SEQCTL);
  1135. if ((ahc->chip & AHC_PCI) != 0) {
  1136. ahc->suspend_state.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
  1137. ahc->suspend_state.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
  1138. }
  1139. if ((ahc->features & AHC_DT) != 0) {
  1140. u_int sfunct;
  1141. sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
  1142. ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
  1143. ahc->suspend_state.optionmode = ahc_inb(ahc, OPTIONMODE);
  1144. ahc_outb(ahc, SFUNCT, sfunct);
  1145. ahc->suspend_state.crccontrol1 = ahc_inb(ahc, CRCCONTROL1);
  1146. }
  1147. if ((ahc->features & AHC_MULTI_FUNC) != 0)
  1148. ahc->suspend_state.scbbaddr = ahc_inb(ahc, SCBBADDR);
  1149. if ((ahc->features & AHC_ULTRA2) != 0)
  1150. ahc->suspend_state.dff_thrsh = ahc_inb(ahc, DFF_THRSH);
  1151. ptr = ahc->suspend_state.scratch_ram;
  1152. for (i = 0; i < 64; i++)
  1153. *ptr++ = ahc_inb(ahc, SRAM_BASE + i);
  1154. if ((ahc->features & AHC_MORE_SRAM) != 0) {
  1155. for (i = 0; i < 16; i++)
  1156. *ptr++ = ahc_inb(ahc, TARG_OFFSET + i);
  1157. }
  1158. ptr = ahc->suspend_state.btt;
  1159. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  1160. for (i = 0;i < AHC_NUM_TARGETS; i++) {
  1161. int j;
  1162. for (j = 0;j < AHC_NUM_LUNS; j++) {
  1163. u_int tcl;
  1164. tcl = BUILD_TCL(i << 4, j);
  1165. *ptr = ahc_index_busy_tcl(ahc, tcl);
  1166. }
  1167. }
  1168. }
  1169. ahc_shutdown(ahc);
  1170. return (0);
  1171. }
  1172. int
  1173. ahc_resume(struct ahc_softc *ahc)
  1174. {
  1175. uint8_t *ptr;
  1176. int  i;
  1177. ahc_reset(ahc);
  1178. ahc_build_free_scb_list(ahc);
  1179. /* Restore volatile registers */
  1180. if ((ahc->features & AHC_TWIN) != 0) {
  1181. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
  1182. ahc_outb(ahc, SCSIID, ahc->our_id);
  1183. ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[1].scsiseq);
  1184. ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[1].sxfrctl0);
  1185. ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[1].sxfrctl1);
  1186. ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[1].simode0);
  1187. ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[1].simode1);
  1188. ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[1].seltimer);
  1189. ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[1].seqctl);
  1190. ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
  1191. }
  1192. ahc_outb(ahc, SCSISEQ, ahc->suspend_state.channel[0].scsiseq);
  1193. ahc_outb(ahc, SXFRCTL0, ahc->suspend_state.channel[0].sxfrctl0);
  1194. ahc_outb(ahc, SXFRCTL1, ahc->suspend_state.channel[0].sxfrctl1);
  1195. ahc_outb(ahc, SIMODE0, ahc->suspend_state.channel[0].simode0);
  1196. ahc_outb(ahc, SIMODE1, ahc->suspend_state.channel[0].simode1);
  1197. ahc_outb(ahc, SELTIMER, ahc->suspend_state.channel[0].seltimer);
  1198. ahc_outb(ahc, SEQCTL, ahc->suspend_state.channel[0].seqctl);
  1199. if ((ahc->features & AHC_ULTRA2) != 0)
  1200. ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
  1201. else
  1202. ahc_outb(ahc, SCSIID, ahc->our_id);
  1203. if ((ahc->chip & AHC_PCI) != 0) {
  1204. ahc_outb(ahc, DSCOMMAND0, ahc->suspend_state.dscommand0);
  1205. ahc_outb(ahc, DSPCISTATUS, ahc->suspend_state.dspcistatus);
  1206. }
  1207. if ((ahc->features & AHC_DT) != 0) {
  1208. u_int sfunct;
  1209. sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE;
  1210. ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE);
  1211. ahc_outb(ahc, OPTIONMODE, ahc->suspend_state.optionmode);
  1212. ahc_outb(ahc, SFUNCT, sfunct);
  1213. ahc_outb(ahc, CRCCONTROL1, ahc->suspend_state.crccontrol1);
  1214. }
  1215. if ((ahc->features & AHC_MULTI_FUNC) != 0)
  1216. ahc_outb(ahc, SCBBADDR, ahc->suspend_state.scbbaddr);
  1217. if ((ahc->features & AHC_ULTRA2) != 0)
  1218. ahc_outb(ahc, DFF_THRSH, ahc->suspend_state.dff_thrsh);
  1219. ptr = ahc->suspend_state.scratch_ram;
  1220. for (i = 0; i < 64; i++)
  1221. ahc_outb(ahc, SRAM_BASE + i, *ptr++);
  1222. if ((ahc->features & AHC_MORE_SRAM) != 0) {
  1223. for (i = 0; i < 16; i++)
  1224. ahc_outb(ahc, TARG_OFFSET + i, *ptr++);
  1225. }
  1226. ptr = ahc->suspend_state.btt;
  1227. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  1228. for (i = 0;i < AHC_NUM_TARGETS; i++) {
  1229. int j;
  1230. for (j = 0;j < AHC_NUM_LUNS; j++) {
  1231. u_int tcl;
  1232. tcl = BUILD_TCL(i << 4, j);
  1233. ahc_busy_tcl(ahc, tcl, *ptr);
  1234. }
  1235. }
  1236. }
  1237. return (0);
  1238. }
  1239. /************************** Busy Target Table *********************************/
  1240. /*
  1241.  * Return the untagged transaction id for a given target/channel lun.
  1242.  * Optionally, clear the entry.
  1243.  */
  1244. u_int
  1245. ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
  1246. {
  1247. u_int scbid;
  1248. u_int target_offset;
  1249. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  1250. u_int saved_scbptr;
  1251. saved_scbptr = ahc_inb(ahc, SCBPTR);
  1252. ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
  1253. scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
  1254. ahc_outb(ahc, SCBPTR, saved_scbptr);
  1255. } else {
  1256. target_offset = TCL_TARGET_OFFSET(tcl);
  1257. scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
  1258. }
  1259. return (scbid);
  1260. }
  1261. void
  1262. ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
  1263. {
  1264. u_int target_offset;
  1265. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  1266. u_int saved_scbptr;
  1267. saved_scbptr = ahc_inb(ahc, SCBPTR);
  1268. ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
  1269. ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
  1270. ahc_outb(ahc, SCBPTR, saved_scbptr);
  1271. } else {
  1272. target_offset = TCL_TARGET_OFFSET(tcl);
  1273. ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
  1274. }
  1275. }
  1276. void
  1277. ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
  1278. {
  1279. u_int target_offset;
  1280. if ((ahc->flags & AHC_SCB_BTT) != 0) {
  1281. u_int saved_scbptr;
  1282. saved_scbptr = ahc_inb(ahc, SCBPTR);
  1283. ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
  1284. ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
  1285. ahc_outb(ahc, SCBPTR, saved_scbptr);
  1286. } else {
  1287. target_offset = TCL_TARGET_OFFSET(tcl);
  1288. ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
  1289. }
  1290. }
  1291. /************************** SCB and SCB queue management **********************/
  1292. int
  1293. ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
  1294.       char channel, int lun, u_int tag, role_t role)
  1295. {
  1296. int targ = SCB_GET_TARGET(ahc, scb);
  1297. char chan = SCB_GET_CHANNEL(ahc, scb);
  1298. int slun = SCB_GET_LUN(scb);
  1299. int match;
  1300. match = ((chan == channel) || (channel == ALL_CHANNELS));
  1301. if (match != 0)
  1302. match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
  1303. if (match != 0)
  1304. match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
  1305. if (match != 0) {
  1306. #if AHC_TARGET_MODE
  1307. int group;
  1308. group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
  1309. if (role == ROLE_INITIATOR) {
  1310. match = (group != XPT_FC_GROUP_TMODE)
  1311.       && ((tag == scb->hscb->tag)
  1312.        || (tag == SCB_LIST_NULL));
  1313. } else if (role == ROLE_TARGET) {
  1314. match = (group == XPT_FC_GROUP_TMODE)
  1315.       && ((tag == scb->io_ctx->csio.tag_id)
  1316.        || (tag == SCB_LIST_NULL));
  1317. }
  1318. #else /* !AHC_TARGET_MODE */
  1319. match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
  1320. #endif /* AHC_TARGET_MODE */
  1321. }
  1322. return match;
  1323. }
  1324. void
  1325. ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
  1326. {
  1327. int target;
  1328. char channel;
  1329. int lun;
  1330. target = SCB_GET_TARGET(ahc, scb);
  1331. lun = SCB_GET_LUN(scb);
  1332. channel = SCB_GET_CHANNEL(ahc, scb);
  1333. ahc_search_qinfifo(ahc, target, channel, lun,
  1334.    /*tag*/SCB_LIST_NULL, ROLE_UNKNOWN,
  1335.    CAM_REQUEUE_REQ, SEARCH_COMPLETE);
  1336. ahc_platform_freeze_devq(ahc, scb);
  1337. }
  1338. void
  1339. ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
  1340. {
  1341. struct scb *prev_scb;
  1342. prev_scb = NULL;
  1343. if (ahc_qinfifo_count(ahc) != 0) {
  1344. u_int prev_tag;
  1345. uint8_t prev_pos;
  1346. prev_pos = ahc->qinfifonext - 1;
  1347. prev_tag = ahc->qinfifo[prev_pos];
  1348. prev_scb = ahc_lookup_scb(ahc, prev_tag);
  1349. }
  1350. ahc_qinfifo_requeue(ahc, prev_scb, scb);
  1351. if ((ahc->features & AHC_QUEUE_REGS) != 0) {
  1352. ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
  1353. } else {
  1354. ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
  1355. }
  1356. }
  1357. static void
  1358. ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
  1359.     struct scb *scb)
  1360. {
  1361. if (prev_scb == NULL) {
  1362. ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
  1363. } else {
  1364. prev_scb->hscb->next = scb->hscb->tag;
  1365. ahc_sync_scb(ahc, prev_scb, 
  1366.      BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  1367. }
  1368. ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
  1369. scb->hscb->next = ahc->next_queued_scb->hscb->tag;
  1370. ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  1371. }
  1372. static int
  1373. ahc_qinfifo_count(struct ahc_softc *ahc)
  1374. {
  1375. u_int8_t qinpos;
  1376. u_int8_t diff;
  1377. if ((ahc->features & AHC_QUEUE_REGS) != 0) {
  1378. qinpos = ahc_inb(ahc, SNSCB_QOFF);
  1379. ahc_outb(ahc, SNSCB_QOFF, qinpos);
  1380. } else
  1381. qinpos = ahc_inb(ahc, QINPOS);
  1382. diff = ahc->qinfifonext - qinpos;
  1383. return (diff);
  1384. }
  1385. int
  1386. ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
  1387.    int lun, u_int tag, role_t role, uint32_t status,
  1388.    ahc_search_action action)
  1389. {
  1390. struct scb *scb;
  1391. struct scb *prev_scb;
  1392. uint8_t qinstart;
  1393. uint8_t qinpos;
  1394. uint8_t qintail;
  1395. uint8_t next;
  1396. uint8_t prev;
  1397. uint8_t curscbptr;
  1398. int found;
  1399. int have_qregs;
  1400. qintail = ahc->qinfifonext;
  1401. have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
  1402. if (have_qregs) {
  1403. qinstart = ahc_inb(ahc, SNSCB_QOFF);
  1404. ahc_outb(ahc, SNSCB_QOFF, qinstart);
  1405. } else
  1406. qinstart = ahc_inb(ahc, QINPOS);
  1407. qinpos = qinstart;
  1408. found = 0;
  1409. prev_scb = NULL;
  1410. if (action == SEARCH_COMPLETE) {
  1411. /*
  1412.  * Don't attempt to run any queued untagged transactions
  1413.  * until we are done with the abort process.
  1414.  */
  1415. ahc_freeze_untagged_queues(ahc);
  1416. }
  1417. /*
  1418.  * Start with an empty queue.  Entries that are not chosen
  1419.  * for removal will be re-added to the queue as we go.
  1420.  */
  1421. ahc->qinfifonext = qinpos;
  1422. ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
  1423. while (qinpos != qintail) {
  1424. scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
  1425. if (scb == NULL) {
  1426. printf("qinpos = %d, SCB index = %dn",
  1427. qinpos, ahc->qinfifo[qinpos]);
  1428. panic("Loop 1n");
  1429. }
  1430. if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
  1431. /*
  1432.  * We found an scb that needs to be acted on.
  1433.  */
  1434. found++;
  1435. switch (action) {
  1436. case SEARCH_COMPLETE:
  1437. {
  1438. cam_status ostat;
  1439. cam_status cstat;
  1440. ostat = ahc_get_transaction_status(scb);
  1441. if (ostat == CAM_REQ_INPROG)
  1442. ahc_set_transaction_status(scb, status);
  1443. cstat = ahc_get_transaction_status(scb);
  1444. if (cstat != CAM_REQ_CMP)
  1445. ahc_freeze_scb(scb);
  1446. if ((scb->flags & SCB_ACTIVE) == 0)
  1447. printf("Inactive SCB in qinfifon");
  1448. ahc_done(ahc, scb);
  1449. /* FALLTHROUGH */
  1450. }
  1451. case SEARCH_REMOVE:
  1452. break;
  1453. case SEARCH_COUNT:
  1454. ahc_qinfifo_requeue(ahc, prev_scb, scb);
  1455. prev_scb = scb;
  1456. break;
  1457. }
  1458. } else {
  1459. ahc_qinfifo_requeue(ahc, prev_scb, scb);
  1460. prev_scb = scb;
  1461. }
  1462. qinpos++;
  1463. }
  1464. if ((ahc->features & AHC_QUEUE_REGS) != 0) {
  1465. ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
  1466. } else {
  1467. ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
  1468. }
  1469. if (action != SEARCH_COUNT
  1470.  && (found != 0)
  1471.  && (qinstart != ahc->qinfifonext)) {
  1472. /*
  1473.  * The sequencer may be in the process of dmaing
  1474.  * down the SCB at the beginning of the queue.
  1475.  * This could be problematic if either the first,
  1476.  * or the second SCB is removed from the queue
  1477.  * (the first SCB includes a pointer to the "next"
  1478.  * SCB to dma). If we have removed any entries, swap
  1479.  * the first element in the queue with the next HSCB
  1480.  * so the sequencer will notice that NEXT_QUEUED_SCB
  1481.  * has changed during its dma attempt and will retry
  1482.  * the DMA.
  1483.  */
  1484. scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
  1485. if (scb == NULL) {
  1486. printf("found = %d, qinstart = %d, qinfifionext = %dn",
  1487. found, qinstart, ahc->qinfifonext);
  1488. panic("First/Second Qinfifo fixupn");
  1489. }
  1490. /*
  1491.  * ahc_swap_with_next_hscb forces our next pointer to
  1492.  * point to the reserved SCB for future commands.  Save
  1493.  * and restore our original next pointer to maintain
  1494.  * queue integrity.
  1495.  */
  1496. next = scb->hscb->next;
  1497. ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
  1498. ahc_swap_with_next_hscb(ahc, scb);
  1499. scb->hscb->next = next;
  1500. ahc->qinfifo[qinstart] = scb->hscb->tag;
  1501. /* Tell the card about the new head of the qinfifo. */
  1502. ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
  1503. /* Fixup the tail "next" pointer. */
  1504. qintail = ahc->qinfifonext - 1;
  1505. scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
  1506. scb->hscb->next = ahc->next_queued_scb->hscb->tag;
  1507. }
  1508. /*
  1509.  * Search waiting for selection list.
  1510.  */
  1511. curscbptr = ahc_inb(ahc, SCBPTR);
  1512. next = ahc_inb(ahc, WAITING_SCBH);  /* Start at head of list. */
  1513. prev = SCB_LIST_NULL;
  1514. while (next != SCB_LIST_NULL) {
  1515. uint8_t scb_index;
  1516. ahc_outb(ahc, SCBPTR, next);
  1517. scb_index = ahc_inb(ahc, SCB_TAG);
  1518. if (scb_index >= ahc->scb_data->numscbs) {
  1519. printf("Waiting List inconsistency. "
  1520.        "SCB index == %d, yet numscbs == %d.",
  1521.        scb_index, ahc->scb_data->numscbs);
  1522. ahc_dump_card_state(ahc);
  1523. panic("for safety");
  1524. }
  1525. scb = ahc_lookup_scb(ahc, scb_index);
  1526. if (scb == NULL) {
  1527. printf("scb_index = %d, next = %dn",
  1528. scb_index, next);
  1529. panic("Waiting List traversaln");
  1530. }
  1531. if (ahc_match_scb(ahc, scb, target, channel,
  1532.   lun, SCB_LIST_NULL, role)) {
  1533. /*
  1534.  * We found an scb that needs to be acted on.
  1535.  */
  1536. found++;
  1537. switch (action) {
  1538. case SEARCH_COMPLETE:
  1539. {
  1540. cam_status ostat;
  1541. cam_status cstat;
  1542. ostat = ahc_get_transaction_status(scb);
  1543. if (ostat == CAM_REQ_INPROG)
  1544. ahc_set_transaction_status(scb,
  1545.    status);
  1546. cstat = ahc_get_transaction_status(scb);
  1547. if (cstat != CAM_REQ_CMP)
  1548. ahc_freeze_scb(scb);
  1549. if ((scb->flags & SCB_ACTIVE) == 0)
  1550. printf("Inactive SCB in Waiting Listn");
  1551. ahc_done(ahc, scb);
  1552. /* FALLTHROUGH */
  1553. }
  1554. case SEARCH_REMOVE:
  1555. next = ahc_rem_wscb(ahc, next, prev);
  1556. break;
  1557. case SEARCH_COUNT:
  1558. prev = next;
  1559. next = ahc_inb(ahc, SCB_NEXT);
  1560. break;
  1561. }
  1562. } else {
  1563. prev = next;
  1564. next = ahc_inb(ahc, SCB_NEXT);
  1565. }
  1566. }
  1567. ahc_outb(ahc, SCBPTR, curscbptr);
  1568. found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
  1569.     channel, lun, status, action);
  1570. if (action == SEARCH_COMPLETE)
  1571. ahc_release_untagged_queues(ahc);
  1572. return (found);
  1573. }
  1574. int
  1575. ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
  1576.    int target, char channel, int lun, uint32_t status,
  1577.    ahc_search_action action)
  1578. {
  1579. struct scb *scb;
  1580. int maxtarget;
  1581. int found;
  1582. int i;
  1583. if (action == SEARCH_COMPLETE) {
  1584. /*
  1585.  * Don't attempt to run any queued untagged transactions
  1586.  * until we are done with the abort process.
  1587.  */
  1588. ahc_freeze_untagged_queues(ahc);
  1589. }
  1590. found = 0;
  1591. i = 0;
  1592. if ((ahc->flags & AHC_SCB_BTT) == 0) {
  1593. maxtarget = 16;
  1594. if (target != CAM_TARGET_WILDCARD) {
  1595. i = target;
  1596. if (channel == 'B')
  1597. i += 8;
  1598. maxtarget = i + 1;
  1599. }
  1600. } else {
  1601. maxtarget = 0;
  1602. }
  1603. for (; i < maxtarget; i++) {
  1604. struct scb_tailq *untagged_q;
  1605. struct scb *next_scb;
  1606. untagged_q = &(ahc->untagged_queues[i]);
  1607. next_scb = TAILQ_FIRST(untagged_q);
  1608. while (next_scb != NULL) {
  1609. scb = next_scb;
  1610. next_scb = TAILQ_NEXT(scb, links.tqe);
  1611. /*
  1612.  * The head of the list may be the currently
  1613.  * active untagged command for a device.
  1614.  * We're only searching for commands that
  1615.  * have not been started.  A transaction
  1616.  * marked active but still in the qinfifo
  1617.  * is removed by the qinfifo scanning code
  1618.  * above.
  1619.  */
  1620. if ((scb->flags & SCB_ACTIVE) != 0)
  1621. continue;
  1622. if (ahc_match_scb(ahc, scb, target, channel, lun,
  1623.   SCB_LIST_NULL, ROLE_INITIATOR) == 0
  1624.  || (ctx != NULL && ctx != scb->io_ctx))
  1625. continue;
  1626. /*
  1627.  * We found an scb that needs to be acted on.
  1628.  */
  1629. found++;
  1630. switch (action) {
  1631. case SEARCH_COMPLETE:
  1632. {
  1633. cam_status ostat;
  1634. cam_status cstat;
  1635. ostat = ahc_get_transaction_status(scb);
  1636. if (ostat == CAM_REQ_INPROG)
  1637. ahc_set_transaction_status(scb, status);
  1638. cstat = ahc_get_transaction_status(scb);
  1639. if (cstat != CAM_REQ_CMP)
  1640. ahc_freeze_scb(scb);
  1641. if ((scb->flags & SCB_ACTIVE) == 0)
  1642. printf("Inactive SCB in untaggedQn");
  1643. ahc_done(ahc, scb);
  1644. break;
  1645. }
  1646. case SEARCH_REMOVE:
  1647. TAILQ_REMOVE(untagged_q, scb, links.tqe);
  1648. break;
  1649. case SEARCH_COUNT:
  1650. break;
  1651. }
  1652. }
  1653. }
  1654. if (action == SEARCH_COMPLETE)
  1655. ahc_release_untagged_queues(ahc);
  1656. return (found);
  1657. }
  1658. int
  1659. ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
  1660.      int lun, u_int tag, int stop_on_first, int remove,
  1661.      int save_state)
  1662. {
  1663. struct scb *scbp;
  1664. u_int next;
  1665. u_int prev;
  1666. u_int count;
  1667. u_int active_scb;
  1668. count = 0;
  1669. next = ahc_inb(ahc, DISCONNECTED_SCBH);
  1670. prev = SCB_LIST_NULL;
  1671. if (save_state) {
  1672. /* restore this when we're done */
  1673. active_scb = ahc_inb(ahc, SCBPTR);
  1674. } else
  1675. /* Silence compiler */
  1676. active_scb = SCB_LIST_NULL;
  1677. while (next != SCB_LIST_NULL) {
  1678. u_int scb_index;
  1679. ahc_outb(ahc, SCBPTR, next);
  1680. scb_index = ahc_inb(ahc, SCB_TAG);
  1681. if (scb_index >= ahc->scb_data->numscbs) {
  1682. printf("Disconnected List inconsistency. "
  1683.        "SCB index == %d, yet numscbs == %d.",
  1684.        scb_index, ahc->scb_data->numscbs);
  1685. ahc_dump_card_state(ahc);
  1686. panic("for safety");
  1687. }
  1688. if (next == prev) {
  1689. panic("Disconnected List Loop. "
  1690.       "cur SCBPTR == %x, prev SCBPTR == %x.",
  1691.       next, prev);
  1692. }
  1693. scbp = ahc_lookup_scb(ahc, scb_index);
  1694. if (ahc_match_scb(ahc, scbp, target, channel, lun,
  1695.   tag, ROLE_INITIATOR)) {
  1696. count++;
  1697. if (remove) {
  1698. next =
  1699.     ahc_rem_scb_from_disc_list(ahc, prev, next);
  1700. } else {
  1701. prev = next;
  1702. next = ahc_inb(ahc, SCB_NEXT);
  1703. }
  1704. if (stop_on_first)
  1705. break;
  1706. } else {
  1707. prev = next;
  1708. next = ahc_inb(ahc, SCB_NEXT);
  1709. }
  1710. }
  1711. if (save_state)
  1712. ahc_outb(ahc, SCBPTR, active_scb);
  1713. return (count);
  1714. }
  1715. /*
  1716.  * Remove an SCB from the on chip list of disconnected transactions.
  1717.  * This is empty/unused if we are not performing SCB paging.
  1718.  */
  1719. static u_int
  1720. ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
  1721. {
  1722. u_int next;
  1723. ahc_outb(ahc, SCBPTR, scbptr);
  1724. next = ahc_inb(ahc, SCB_NEXT);
  1725. ahc_outb(ahc, SCB_CONTROL, 0);
  1726. ahc_add_curscb_to_free_list(ahc);
  1727. if (prev != SCB_LIST_NULL) {
  1728. ahc_outb(ahc, SCBPTR, prev);
  1729. ahc_outb(ahc, SCB_NEXT, next);
  1730. } else
  1731. ahc_outb(ahc, DISCONNECTED_SCBH, next);
  1732. return (next);
  1733. }
  1734. /*
  1735.  * Add the SCB as selected by SCBPTR onto the on chip list of
  1736.  * free hardware SCBs.  This list is empty/unused if we are not
  1737.  * performing SCB paging.
  1738.  */
  1739. static void
  1740. ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
  1741. {
  1742. /*
  1743.  * Invalidate the tag so that our abort
  1744.  * routines don't think it's active.
  1745.  */
  1746. ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
  1747. if ((ahc->flags & AHC_PAGESCBS) != 0) {
  1748. ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
  1749. ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
  1750. }
  1751. }
  1752. /*
  1753.  * Manipulate the waiting for selection list and return the
  1754.  * scb that follows the one that we remove.
  1755.  */
  1756. static u_int
  1757. ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
  1758. {       
  1759. u_int curscb, next;
  1760. /*
  1761.  * Select the SCB we want to abort and
  1762.  * pull the next pointer out of it.
  1763.  */
  1764. curscb = ahc_inb(ahc, SCBPTR);
  1765. ahc_outb(ahc, SCBPTR, scbpos);
  1766. next = ahc_inb(ahc, SCB_NEXT);
  1767. /* Clear the necessary fields */
  1768. ahc_outb(ahc, SCB_CONTROL, 0);
  1769. ahc_add_curscb_to_free_list(ahc);
  1770. /* update the waiting list */
  1771. if (prev == SCB_LIST_NULL) {
  1772. /* First in the list */
  1773. ahc_outb(ahc, WAITING_SCBH, next); 
  1774. /*
  1775.  * Ensure we aren't attempting to perform
  1776.  * selection for this entry.
  1777.  */
  1778. ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
  1779. } else {
  1780. /*
  1781.  * Select the scb that pointed to us 
  1782.  * and update its next pointer.
  1783.  */
  1784. ahc_outb(ahc, SCBPTR, prev);
  1785. ahc_outb(ahc, SCB_NEXT, next);
  1786. }
  1787. /*
  1788.  * Point us back at the original scb position.
  1789.  */
  1790. ahc_outb(ahc, SCBPTR, curscb);
  1791. return next;
  1792. }
  1793. /******************************** Error Handling ******************************/
  1794. /*
  1795.  * Abort all SCBs that match the given description (target/channel/lun/tag),
  1796.  * setting their status to the passed in status if the status has not already
  1797.  * been modified from CAM_REQ_INPROG.  This routine assumes that the sequencer
  1798.  * is paused before it is called.
  1799.  */
  1800. int
  1801. ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
  1802.        int lun, u_int tag, role_t role, uint32_t status)
  1803. {
  1804. struct scb *scbp;
  1805. struct scb *scbp_next;
  1806. u_int active_scb;
  1807. int i, j;
  1808. int maxtarget;
  1809. int minlun;
  1810. int maxlun;
  1811. int found;
  1812. /*
  1813.  * Don't attempt to run any queued untagged transactions
  1814.  * until we are done with the abort process.
  1815.  */
  1816. ahc_freeze_untagged_queues(ahc);
  1817. /* restore this when we're done */
  1818. active_scb = ahc_inb(ahc, SCBPTR);
  1819. found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
  1820.    role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
  1821. /*
  1822.  * Clean out the busy target table for any untagged commands.
  1823.  */
  1824. i = 0;
  1825. maxtarget = 16;
  1826. if (target != CAM_TARGET_WILDCARD) {
  1827. i = target;
  1828. if (channel == 'B')
  1829. i += 8;
  1830. maxtarget = i + 1;
  1831. }
  1832. if (lun == CAM_LUN_WILDCARD) {
  1833. /*
  1834.  * Unless we are using an SCB based
  1835.  * busy targets table, there is only
  1836.  * one table entry for all luns of
  1837.  * a target.
  1838.  */
  1839. minlun = 0;
  1840. maxlun = 1;
  1841. if ((ahc->flags & AHC_SCB_BTT) != 0)
  1842. maxlun = AHC_NUM_LUNS;
  1843. } else {
  1844. minlun = lun;
  1845. maxlun = lun + 1;
  1846. }
  1847. if (role != ROLE_TARGET) {
  1848. for (;i < maxtarget; i++) {
  1849. for (j = minlun;j < maxlun; j++) {
  1850. u_int scbid;
  1851. u_int tcl;
  1852. tcl = BUILD_TCL(i << 4, j);
  1853. scbid = ahc_index_busy_tcl(ahc, tcl);
  1854. scbp = ahc_lookup_scb(ahc, scbid);
  1855. if (scbp == NULL
  1856.  || ahc_match_scb(ahc, scbp, target, channel,
  1857.   lun, tag, role) == 0)
  1858. continue;
  1859. ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
  1860. }
  1861. }
  1862. /*
  1863.  * Go through the disconnected list and remove any entries we
  1864.  * have queued for completion, 0'ing their control byte too.
  1865.  * We save the active SCB and restore it ourselves, so there
  1866.  * is no reason for this search to restore it too.
  1867.  */
  1868. ahc_search_disc_list(ahc, target, channel, lun, tag,
  1869.      /*stop_on_first*/FALSE, /*remove*/TRUE,
  1870.      /*save_state*/FALSE);
  1871. }
  1872. /*
  1873.  * Go through the hardware SCB array looking for commands that
  1874.  * were active but not on any list.  In some cases, these remnants
  1875.  * might not still have mappings in the scbindex array (e.g. unexpected
  1876.  * bus free with the same scb queued for an abort).  Don't hold this
  1877.  * against them.
  1878.  */
  1879. for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
  1880. u_int scbid;
  1881. ahc_outb(ahc, SCBPTR, i);
  1882. scbid = ahc_inb(ahc, SCB_TAG);
  1883. scbp = ahc_lookup_scb(ahc, scbid);
  1884. if ((scbp == NULL && scbid != SCB_LIST_NULL)
  1885.  || (scbp != NULL
  1886.   && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
  1887. ahc_add_curscb_to_free_list(ahc);
  1888. }
  1889. /*
  1890.  * Go through the pending CCB list and look for
  1891.  * commands for this target that are still active.
  1892.  * These are other tagged commands that were
  1893.  * disconnected when the reset occurred.
  1894.  */
  1895. scbp_next = LIST_FIRST(&ahc->pending_scbs);
  1896. while (scbp_next != NULL) {
  1897. scbp = scbp_next;
  1898. scbp_next = LIST_NEXT(scbp, pending_links);
  1899. if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
  1900. cam_status ostat;
  1901. ostat = ahc_get_transaction_status(scbp);
  1902. if (ostat == CAM_REQ_INPROG)
  1903. ahc_set_transaction_status(scbp, status);
  1904. if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
  1905. ahc_freeze_scb(scbp);
  1906. if ((scbp->flags & SCB_ACTIVE) == 0)
  1907. printf("Inactive SCB on pending listn");
  1908. ahc_done(ahc, scbp);
  1909. found++;
  1910. }
  1911. }
  1912. ahc_outb(ahc, SCBPTR, active_scb);
  1913. ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
  1914. ahc_release_untagged_queues(ahc);
  1915. return found;
  1916. }
  1917. static void
  1918. ahc_reset_current_bus(struct ahc_softc *ahc)
  1919. {
  1920. uint8_t scsiseq;
  1921. ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
  1922. scsiseq = ahc_inb(ahc, SCSISEQ);
  1923. ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
  1924. ahc_flush_device_writes(ahc);
  1925. ahc_delay(AHC_BUSRESET_DELAY);
  1926. /* Turn off the bus reset */
  1927. ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
  1928. ahc_clear_intstat(ahc);
  1929. /* Re-enable reset interrupts */
  1930. ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
  1931. }
  1932. int
  1933. ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
  1934. {
  1935. struct ahc_devinfo devinfo;
  1936. u_int initiator, target, max_scsiid;
  1937. u_int sblkctl;
  1938. u_int scsiseq;
  1939. u_int simode1;
  1940. int found;
  1941. int restart_needed;
  1942. char cur_channel;
  1943. ahc->pending_device = NULL;
  1944. ahc_compile_devinfo(&devinfo,
  1945.     CAM_TARGET_WILDCARD,
  1946.     CAM_TARGET_WILDCARD,
  1947.     CAM_LUN_WILDCARD,
  1948.     channel, ROLE_UNKNOWN);
  1949. ahc_pause(ahc);
  1950. /* Make sure the sequencer is in a safe location. */
  1951. ahc_clear_critical_section(ahc);
  1952. /*
  1953.  * Run our command complete fifos to ensure that we perform
  1954.  * completion processing on any commands that 'completed'
  1955.  * before the reset occurred.
  1956.  */
  1957. ahc_run_qoutfifo(ahc);
  1958. #if AHC_TARGET_MODE
  1959. /*
  1960.  * XXX - In Twin mode, the tqinfifo may have commands
  1961.  *  for an unaffected channel in it.  However, if
  1962.  *  we have run out of ATIO resources to drain that
  1963.  *  queue, we may not get them all out here.  Further,
  1964.  *  the blocked transactions for the reset channel
  1965.  *  should just be killed off, irrespecitve of whether
  1966.  *  we are blocked on ATIO resources.  Write a routine
  1967.  *  to compact the tqinfifo appropriately.
  1968.  */
  1969. if ((ahc->flags & AHC_TARGETROLE) != 0) {
  1970. ahc_run_tqinfifo(ahc, /*paused*/TRUE);
  1971. }
  1972. #endif
  1973. /*
  1974.  * Reset the bus if we are initiating this reset
  1975.  */
  1976. sblkctl = ahc_inb(ahc, SBLKCTL);
  1977. cur_channel = 'A';
  1978. if ((ahc->features & AHC_TWIN) != 0
  1979.  && ((sblkctl & SELBUSB) != 0))
  1980.     cur_channel = 'B';
  1981. scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
  1982. if (cur_channel != channel) {
  1983. /* Case 1: Command for another bus is active
  1984.  * Stealthily reset the other bus without
  1985.  * upsetting the current bus.
  1986.  */
  1987. ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
  1988. simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
  1989. #if AHC_TARGET_MODE
  1990. /*
  1991.  * Bus resets clear ENSELI, so we cannot
  1992.  * defer re-enabling bus reset interrupts
  1993.  * if we are in target mode.
  1994.  */
  1995. if ((ahc->flags & AHC_TARGETROLE) != 0)
  1996. simode1 |= ENSCSIRST;
  1997. #endif
  1998. ahc_outb(ahc, SIMODE1, simode1);
  1999. if (initiate_reset)
  2000. ahc_reset_current_bus(ahc);
  2001. ahc_clear_intstat(ahc);
  2002. ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
  2003. ahc_outb(ahc, SBLKCTL, sblkctl);
  2004. restart_needed = FALSE;
  2005. } else {
  2006. /* Case 2: A command from this bus is active or we're idle */
  2007. simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
  2008. #if AHC_TARGET_MODE
  2009. /*
  2010.  * Bus resets clear ENSELI, so we cannot
  2011.  * defer re-enabling bus reset interrupts
  2012.  * if we are in target mode.
  2013.  */
  2014. if ((ahc->flags & AHC_TARGETROLE) != 0)
  2015. simode1 |= ENSCSIRST;
  2016. #endif
  2017. ahc_outb(ahc, SIMODE1, simode1);
  2018. if (initiate_reset)
  2019. ahc_reset_current_bus(ahc);
  2020. ahc_clear_intstat(ahc);
  2021. ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
  2022. restart_needed = TRUE;
  2023. }
  2024. /*
  2025.  * Clean up all the state information for the
  2026.  * pending transactions on this bus.
  2027.  */
  2028. found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
  2029.        CAM_LUN_WILDCARD, SCB_LIST_NULL,
  2030.        ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
  2031. max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
  2032. #ifdef AHC_TARGET_MODE
  2033. /*
  2034.  * Send an immediate notify ccb to all target more peripheral
  2035.  * drivers affected by this action.
  2036.  */
  2037. for (target = 0; target <= max_scsiid; target++) {
  2038. struct ahc_tmode_tstate* tstate;
  2039. u_int lun;
  2040. tstate = ahc->enabled_targets[target];
  2041. if (tstate == NULL)
  2042. continue;
  2043. for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
  2044. struct ahc_tmode_lstate* lstate;
  2045. lstate = tstate->enabled_luns[lun];
  2046. if (lstate == NULL)
  2047. continue;
  2048. ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
  2049.        EVENT_TYPE_BUS_RESET, /*arg*/0);
  2050. ahc_send_lstate_events(ahc, lstate);
  2051. }
  2052. }
  2053. #endif
  2054. /* Notify the XPT that a bus reset occurred */
  2055. ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
  2056.        CAM_LUN_WILDCARD, AC_BUS_RESET, NULL);
  2057. /*
  2058.  * Revert to async/narrow transfers until we renegotiate.
  2059.  */
  2060. for (target = 0; target <= max_scsiid; target++) {
  2061. if (ahc->enabled_targets[target] == NULL)
  2062. continue;
  2063. for (initiator = 0; initiator <= max_scsiid; initiator++) {
  2064. struct ahc_devinfo devinfo;
  2065. ahc_compile_devinfo(&devinfo, target, initiator,
  2066.     CAM_LUN_WILDCARD,
  2067.     channel, ROLE_UNKNOWN);
  2068. ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
  2069.       AHC_TRANS_CUR, /*paused*/TRUE);
  2070. ahc_set_syncrate(ahc, &devinfo, /*syncrate*/NULL,
  2071.  /*period*/0, /*offset*/0,
  2072.  /*ppr_options*/0, AHC_TRANS_CUR,
  2073.  /*paused*/TRUE);
  2074. }
  2075. }
  2076. if (restart_needed)
  2077. ahc_restart(ahc);
  2078. else
  2079. ahc_unpause(ahc);
  2080. return found;
  2081. }
  2082. /***************************** Residual Processing ****************************/
  2083. /*
  2084.  * Calculate the residual for a just completed SCB.
  2085.  */
  2086. void
  2087. ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
  2088. {
  2089. struct hardware_scb *hscb;
  2090. struct status_pkt *spkt;
  2091. uint32_t sgptr;
  2092. uint32_t resid_sgptr;
  2093. uint32_t resid;
  2094. /*
  2095.  * 5 cases.
  2096.  * 1) No residual.
  2097.  *    SG_RESID_VALID clear in sgptr.
  2098.  * 2) Transferless command
  2099.  * 3) Never performed any transfers.
  2100.  *    sgptr has SG_FULL_RESID set.
  2101.  * 4) No residual but target did not
  2102.  *    save data pointers after the
  2103.  *    last transfer, so sgptr was
  2104.  *    never updated.
  2105.  * 5) We have a partial residual.
  2106.  *    Use residual_sgptr to determine
  2107.  *    where we are.
  2108.  */
  2109. hscb = scb->hscb;
  2110. sgptr = ahc_le32toh(hscb->sgptr);
  2111. if ((sgptr & SG_RESID_VALID) == 0)
  2112. /* Case 1 */
  2113. return;
  2114. sgptr &= ~SG_RESID_VALID;
  2115. if ((sgptr & SG_LIST_NULL) != 0)
  2116. /* Case 2 */
  2117. return;
  2118. spkt = &hscb->shared_data.status;
  2119. resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
  2120. if ((sgptr & SG_FULL_RESID) != 0) {
  2121. /* Case 3 */
  2122. resid = ahc_get_transfer_length(scb);
  2123. } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
  2124. /* Case 4 */
  2125. return;
  2126. } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
  2127. panic("Bogus resid sgptr value 0x%xn", resid_sgptr);
  2128. } else {
  2129. struct ahc_dma_seg *sg;
  2130. /*
  2131.  * Remainder of the SG where the transfer
  2132.  * stopped.  
  2133.  */
  2134. resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
  2135. sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
  2136. /* The residual sg_ptr always points to the next sg */
  2137. sg--;
  2138. /*
  2139.  * Add up the contents of all residual
  2140.  * SG segments that are after the SG where
  2141.  * the transfer stopped.
  2142.  */
  2143. while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
  2144. sg++;
  2145. resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
  2146. }
  2147. }
  2148. if ((scb->flags & SCB_SENSE) == 0)
  2149. ahc_set_residual(scb, resid);
  2150. else
  2151. ahc_set_sense_residual(scb, resid);
  2152. #ifdef AHC_DEBUG
  2153. if ((ahc_debug & AHC_SHOWMISC) != 0) {
  2154. ahc_print_path(ahc, scb);
  2155. printf("Handled Residual of %d bytesn", resid);
  2156. }
  2157. #endif
  2158. }
  2159. /******************************* Target Mode **********************************/
  2160. #ifdef AHC_TARGET_MODE
  2161. /*
  2162.  * Add a target mode event to this lun's queue
  2163.  */
  2164. static void
  2165. ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
  2166.        u_int initiator_id, u_int event_type, u_int event_arg)
  2167. {
  2168. struct ahc_tmode_event *event;
  2169. int pending;
  2170. xpt_freeze_devq(lstate->path, /*count*/1);
  2171. if (lstate->event_w_idx >= lstate->event_r_idx)
  2172. pending = lstate->event_w_idx - lstate->event_r_idx;
  2173. else
  2174. pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
  2175. - (lstate->event_r_idx - lstate->event_w_idx);
  2176. if (event_type == EVENT_TYPE_BUS_RESET
  2177.  || event_type == MSG_BUS_DEV_RESET) {
  2178. /*
  2179.  * Any earlier events are irrelevant, so reset our buffer.
  2180.  * This has the effect of allowing us to deal with reset
  2181.  * floods (an external device holding down the reset line)
  2182.  * without losing the event that is really interesting.
  2183.  */
  2184. lstate->event_r_idx = 0;
  2185. lstate->event_w_idx = 0;
  2186. xpt_release_devq(lstate->path, pending, /*runqueue*/FALSE);
  2187. }
  2188. if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
  2189. xpt_print_path(lstate->path);
  2190. printf("immediate event %x:%x lostn",
  2191.        lstate->event_buffer[lstate->event_r_idx].event_type,
  2192.        lstate->event_buffer[lstate->event_r_idx].event_arg);
  2193. lstate->event_r_idx++;
  2194. if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
  2195. lstate->event_r_idx = 0;
  2196. xpt_release_devq(lstate->path, /*count*/1, /*runqueue*/FALSE);
  2197. }
  2198. event = &lstate->event_buffer[lstate->event_w_idx];
  2199. event->initiator_id = initiator_id;
  2200. event->event_type = event_type;
  2201. event->event_arg = event_arg;
  2202. lstate->event_w_idx++;
  2203. if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
  2204. lstate->event_w_idx = 0;
  2205. }
  2206. /*
  2207.  * Send any target mode events queued up waiting
  2208.  * for immediate notify resources.
  2209.  */
  2210. void
  2211. ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
  2212. {
  2213. struct ccb_hdr *ccbh;
  2214. struct ccb_immed_notify *inot;
  2215. while (lstate->event_r_idx != lstate->event_w_idx
  2216.     && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
  2217. struct ahc_tmode_event *event;
  2218. event = &lstate->event_buffer[lstate->event_r_idx];
  2219. SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
  2220. inot = (struct ccb_immed_notify *)ccbh;
  2221. switch (event->event_type) {
  2222. case EVENT_TYPE_BUS_RESET:
  2223. ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
  2224. break;
  2225. default:
  2226. ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
  2227. inot->message_args[0] = event->event_type;
  2228. inot->message_args[1] = event->event_arg;
  2229. break;
  2230. }
  2231. inot->initiator_id = event->initiator_id;
  2232. inot->sense_len = 0;
  2233. xpt_done((union ccb *)inot);
  2234. lstate->event_r_idx++;
  2235. if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
  2236. lstate->event_r_idx = 0;
  2237. }
  2238. }
  2239. #endif
  2240. /******************** Sequencer Program Patching/Download *********************/
  2241. #ifdef AHC_DUMP_SEQ
  2242. void
  2243. ahc_dumpseq(struct ahc_softc* ahc)
  2244. {
  2245. int i;
  2246. int max_prog;
  2247. if ((ahc->chip & AHC_BUS_MASK) < AHC_PCI)
  2248. max_prog = 448;
  2249. else if ((ahc->features & AHC_ULTRA2) != 0)
  2250. max_prog = 768;
  2251. else
  2252. max_prog = 512;
  2253. ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
  2254. ahc_outb(ahc, SEQADDR0, 0);
  2255. ahc_outb(ahc, SEQADDR1, 0);
  2256. for (i = 0; i < max_prog; i++) {
  2257. uint8_t ins_bytes[4];
  2258. ahc_insb(ahc, SEQRAM, ins_bytes, 4);
  2259. printf("0x%08xn", ins_bytes[0] << 24
  2260.  | ins_bytes[1] << 16
  2261.  | ins_bytes[2] << 8
  2262.  | ins_bytes[3]);
  2263. }
  2264. }
  2265. #endif
  2266. static void
  2267. ahc_loadseq(struct ahc_softc *ahc)
  2268. {
  2269. struct cs cs_table[num_critical_sections];
  2270. u_int begin_set[num_critical_sections];
  2271. u_int end_set[num_critical_sections];
  2272. struct patch *cur_patch;
  2273. u_int cs_count;
  2274. u_int cur_cs;
  2275. u_int i;
  2276. int downloaded;
  2277. u_int skip_addr;
  2278. u_int sg_prefetch_cnt;
  2279. uint8_t download_consts[7];
  2280. /*
  2281.  * Start out with 0 critical sections
  2282.  * that apply to this firmware load.
  2283.  */
  2284. cs_count = 0;
  2285. cur_cs = 0;
  2286. memset(begin_set, 0, sizeof(begin_set));
  2287. memset(end_set, 0, sizeof(end_set));
  2288. /* Setup downloadable constant table */
  2289. download_consts[QOUTFIFO_OFFSET] = 0;
  2290. if (ahc->targetcmds != NULL)
  2291. download_consts[QOUTFIFO_OFFSET] += 32;
  2292. download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
  2293. download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
  2294. download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
  2295. sg_prefetch_cnt = ahc->pci_cachesize;
  2296. if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
  2297. sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
  2298. download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
  2299. download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
  2300. download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
  2301. cur_patch = patches;
  2302. downloaded = 0;
  2303. skip_addr = 0;
  2304. ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
  2305. ahc_outb(ahc, SEQADDR0, 0);
  2306. ahc_outb(ahc, SEQADDR1, 0);
  2307. for (i = 0; i < sizeof(seqprog)/4; i++) {
  2308. if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
  2309. /*
  2310.  * Don't download this instruction as it
  2311.  * is in a patch that was removed.
  2312.  */
  2313. continue;
  2314. }
  2315. /*
  2316.  * Move through the CS table until we find a CS
  2317.  * that might apply to this instruction.
  2318.  */
  2319. for (; cur_cs < num_critical_sections; cur_cs++) {
  2320. if (critical_sections[cur_cs].end <= i) {
  2321. if (begin_set[cs_count] == TRUE
  2322.  && end_set[cs_count] == FALSE) {
  2323. cs_table[cs_count].end = downloaded;
  2324.   end_set[cs_count] = TRUE;
  2325. cs_count++;
  2326. }
  2327. continue;
  2328. }
  2329. if (critical_sections[cur_cs].begin <= i
  2330.  && begin_set[cs_count] == FALSE) {
  2331. cs_table[cs_count].begin = downloaded;
  2332. begin_set[cs_count] = TRUE;
  2333. }
  2334. break;
  2335. }
  2336. ahc_download_instr(ahc, i, download_consts);
  2337. downloaded++;
  2338. }
  2339. ahc->num_critical_sections = cs_count;
  2340. if (cs_count != 0) {
  2341. cs_count *= sizeof(struct cs);
  2342. ahc->critical_sections = malloc(cs_count, M_DEVBUF, M_NOWAIT);
  2343. if (ahc->critical_sections == NULL)
  2344. panic("ahc_loadseq: Could not malloc");
  2345. memcpy(ahc->critical_sections, cs_table, cs_count);
  2346. }
  2347. ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
  2348. ahc_restart(ahc);
  2349. if (bootverbose)
  2350. printf(" %d instructions downloadedn", downloaded);
  2351. }
  2352. static int
  2353. ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
  2354. u_int start_instr, u_int *skip_addr)
  2355. {
  2356. struct patch *cur_patch;
  2357. struct patch *last_patch;
  2358. u_int num_patches;
  2359. num_patches = sizeof(patches)/sizeof(struct patch);
  2360. last_patch = &patches[num_patches];
  2361. cur_patch = *start_patch;
  2362. while (cur_patch < last_patch && start_instr == cur_patch->begin) {
  2363. if (cur_patch->patch_func(ahc) == 0) {
  2364. /* Start rejecting code */
  2365. *skip_addr = start_instr + cur_patch->skip_instr;
  2366. cur_patch += cur_patch->skip_patch;
  2367. } else {
  2368. /* Accepted this patch.  Advance to the next
  2369.  * one and wait for our intruction pointer to
  2370.  * hit this point.
  2371.  */
  2372. cur_patch++;
  2373. }
  2374. }
  2375. *start_patch = cur_patch;
  2376. if (start_instr < *skip_addr)
  2377. /* Still skipping */
  2378. return (0);
  2379. return (1);
  2380. }
  2381. static void
  2382. ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
  2383. {
  2384. union ins_formats instr;
  2385. struct ins_format1 *fmt1_ins;
  2386. struct ins_format3 *fmt3_ins;
  2387. u_int opcode;
  2388. /*
  2389.  * The firmware is always compiled into a little endian format.
  2390.  */
  2391. instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
  2392. fmt1_ins = &instr.format1;
  2393. fmt3_ins = NULL;
  2394. /* Pull the opcode */
  2395. opcode = instr.format1.opcode;
  2396. switch (opcode) {
  2397. case AIC_OP_JMP:
  2398. case AIC_OP_JC:
  2399. case AIC_OP_JNC:
  2400. case AIC_OP_CALL:
  2401. case AIC_OP_JNE:
  2402. case AIC_OP_JNZ:
  2403. case AIC_OP_JE:
  2404. case AIC_OP_JZ:
  2405. {
  2406. struct patch *cur_patch;
  2407. int address_offset;
  2408. u_int address;
  2409. u_int skip_addr;
  2410. u_int i;
  2411. fmt3_ins = &instr.format3;
  2412. address_offset = 0;
  2413. address = fmt3_ins->address;
  2414. cur_patch = patches;
  2415. skip_addr = 0;
  2416. for (i = 0; i < address;) {
  2417. ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
  2418. if (skip_addr > i) {
  2419. int end_addr;
  2420. end_addr = MIN(address, skip_addr);
  2421. address_offset += end_addr - i;
  2422. i = skip_addr;
  2423. } else {
  2424. i++;
  2425. }
  2426. }
  2427. address -= address_offset;
  2428. fmt3_ins->address = address;
  2429. /* FALLTHROUGH */
  2430. }
  2431. case AIC_OP_OR:
  2432. case AIC_OP_AND:
  2433. case AIC_OP_XOR:
  2434. case AIC_OP_ADD:
  2435. case AIC_OP_ADC:
  2436. case AIC_OP_BMOV:
  2437. if (fmt1_ins->parity != 0) {
  2438. fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
  2439. }
  2440. fmt1_ins->parity = 0;
  2441. if ((ahc->features & AHC_CMD_CHAN) == 0
  2442.  && opcode == AIC_OP_BMOV) {
  2443. /*
  2444.  * Block move was added at the same time
  2445.  * as the command channel.  Verify that
  2446.  * this is only a move of a single element
  2447.  * and convert the BMOV to a MOV
  2448.  * (AND with an immediate of FF).
  2449.  */
  2450. if (fmt1_ins->immediate != 1)
  2451. panic("%s: BMOV not supportedn",
  2452.       ahc_name(ahc));
  2453. fmt1_ins->opcode = AIC_OP_AND;
  2454. fmt1_ins->immediate = 0xff;
  2455. }
  2456. /* FALLTHROUGH */
  2457. case AIC_OP_ROL:
  2458. if ((ahc->features & AHC_ULTRA2) != 0) {
  2459. int i, count;
  2460. /* Calculate odd parity for the instruction */
  2461. for (i = 0, count = 0; i < 31; i++) {
  2462. uint32_t mask;
  2463. mask = 0x01 << i;
  2464. if ((instr.integer & mask) != 0)
  2465. count++;
  2466. }
  2467. if ((count & 0x01) == 0)
  2468. instr.format1.parity = 1;
  2469. } else {
  2470. /* Compress the instruction for older sequencers */
  2471. if (fmt3_ins != NULL) {
  2472. instr.integer =
  2473. fmt3_ins->immediate
  2474.       | (fmt3_ins->source << 8)
  2475.       | (fmt3_ins->address << 16)
  2476.       | (fmt3_ins->opcode << 25);
  2477. } else {
  2478. instr.integer =
  2479. fmt1_ins->immediate
  2480.       | (fmt1_ins->source << 8)
  2481.       | (fmt1_ins->destination << 16)
  2482.       | (fmt1_ins->ret << 24)
  2483.       | (fmt1_ins->opcode << 25);
  2484. }
  2485. }
  2486. /* The sequencer is a little endian cpu */
  2487. instr.integer = ahc_htole32(instr.integer);
  2488. ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
  2489. break;
  2490. default:
  2491. panic("Unknown opcode encountered in seq program");
  2492. break;
  2493. }
  2494. }
  2495. void
  2496. ahc_dump_card_state(struct ahc_softc *ahc)
  2497. {
  2498. struct scb *scb;
  2499. struct scb_tailq *untagged_q;
  2500. int target;
  2501. int maxtarget;
  2502. int i;
  2503. uint8_t last_phase;
  2504. uint8_t qinpos;
  2505. uint8_t qintail;
  2506. uint8_t qoutpos;
  2507. uint8_t scb_index;
  2508. uint8_t saved_scbptr;
  2509. saved_scbptr = ahc_inb(ahc, SCBPTR);
  2510. last_phase = ahc_inb(ahc, LASTPHASE);
  2511. printf("%s: Dumping Card State %s, at SEQADDR 0x%xn",
  2512.        ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
  2513.        ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
  2514. printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%xn",
  2515.        ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
  2516.        ahc_inb(ahc, ARG_2));
  2517. printf("HCNT = 0x%x SCBPTR = 0x%xn", ahc_inb(ahc, HCNT),
  2518.        ahc_inb(ahc, SCBPTR));
  2519. printf("SCSISEQ = 0x%x, SBLKCTL = 0x%xn",
  2520.        ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL));
  2521. printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%xn",
  2522.        ahc_inb(ahc, DFCNTRL), ahc_inb(ahc, DFSTATUS));
  2523. printf("LASTPHASE = 0x%x, SCSISIGI = 0x%x, SXFRCTL0 = 0x%xn",
  2524.        last_phase, ahc_inb(ahc, SCSISIGI), ahc_inb(ahc, SXFRCTL0));
  2525. printf("SSTAT0 = 0x%x, SSTAT1 = 0x%xn",
  2526.        ahc_inb(ahc, SSTAT0), ahc_inb(ahc, SSTAT1));
  2527. if ((ahc->features & AHC_DT) != 0)
  2528. printf("SCSIPHASE = 0x%xn", ahc_inb(ahc, SCSIPHASE));
  2529. printf("STACK == 0x%x, 0x%x, 0x%x, 0x%xn",
  2530. ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
  2531. ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
  2532. ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8),
  2533. ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8));
  2534. printf("SCB count = %dn", ahc->scb_data->numscbs);
  2535. printf("Kernel NEXTQSCB = %dn", ahc->next_queued_scb->hscb->tag);
  2536. printf("Card NEXTQSCB = %dn", ahc_inb(ahc, NEXT_QUEUED_SCB));
  2537. /* QINFIFO */
  2538. printf("QINFIFO entries: ");
  2539. if ((ahc->features & AHC_QUEUE_REGS) != 0) {
  2540. qinpos = ahc_inb(ahc, SNSCB_QOFF);
  2541. ahc_outb(ahc, SNSCB_QOFF, qinpos);
  2542. } else
  2543. qinpos = ahc_inb(ahc, QINPOS);
  2544. qintail = ahc->qinfifonext;
  2545. while (qinpos != qintail) {
  2546. printf("%d ", ahc->qinfifo[qinpos]);
  2547. qinpos++;
  2548. }
  2549. printf("n");
  2550. printf("Waiting Queue entries: ");
  2551. scb_index = ahc_inb(ahc, WAITING_SCBH);
  2552. i = 0;
  2553. while (scb_index != SCB_LIST_NULL && i++ < 256) {
  2554. ahc_outb(ahc, SCBPTR, scb_index);
  2555. printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
  2556. scb_index = ahc_inb(ahc, SCB_NEXT);
  2557. }
  2558. printf("n");
  2559. printf("Disconnected Queue entries: ");
  2560. scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
  2561. i = 0;
  2562. while (scb_index != SCB_LIST_NULL && i++ < 256) {
  2563. ahc_outb(ahc, SCBPTR, scb_index);
  2564. printf("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
  2565. scb_index = ahc_inb(ahc, SCB_NEXT);
  2566. }
  2567. printf("n");
  2568. ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
  2569. printf("QOUTFIFO entries: ");
  2570. qoutpos = ahc->qoutfifonext;
  2571. i = 0;
  2572. while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
  2573. printf("%d ", ahc->qoutfifo[qoutpos]);
  2574. qoutpos++;
  2575. }
  2576. printf("n");
  2577. printf("Sequencer Free SCB List: ");
  2578. scb_index = ahc_inb(ahc, FREE_SCBH);
  2579. i = 0;
  2580. while (scb_index != SCB_LIST_NULL && i++ < 256) {
  2581. ahc_outb(ahc, SCBPTR, scb_index);
  2582. printf("%d ", scb_index);
  2583. scb_index = ahc_inb(ahc, SCB_NEXT);
  2584. }
  2585. printf("n");
  2586. printf("Sequencer SCB Info: ");
  2587. for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
  2588. ahc_outb(ahc, SCBPTR, i);
  2589. printf("%d(c 0x%x, s 0x%x, l %d, t 0x%x) ",
  2590.        i, ahc_inb(ahc, SCB_CONTROL),
  2591.        ahc_inb(ahc, SCB_SCSIID),
  2592.        ahc_inb(ahc, SCB_LUN),
  2593.        ahc_inb(ahc, SCB_TAG));
  2594. }
  2595. printf("n");
  2596. printf("Pending list: ");
  2597. i = 0;
  2598. LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
  2599. if (i++ > 256)
  2600. break;
  2601. if (scb != LIST_FIRST(&ahc->pending_scbs))
  2602. printf(", ");
  2603. printf("%d(c 0x%x, s 0x%x, l %d)", scb->hscb->tag,
  2604.        scb->hscb->control, scb->hscb->scsiid, scb->hscb->lun);
  2605. if ((ahc->flags & AHC_PAGESCBS) == 0) {
  2606. ahc_outb(ahc, SCBPTR, scb->hscb->tag);
  2607. printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL),
  2608.        ahc_inb(ahc, SCB_TAG));
  2609. }
  2610. }
  2611. printf("n");
  2612. printf("Kernel Free SCB list: ");
  2613. i = 0;
  2614. SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
  2615. if (i++ > 256)
  2616. break;
  2617. printf("%d ", scb->hscb->tag);
  2618. }
  2619. printf("n");
  2620. maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
  2621. for (target = 0; target <= maxtarget; target++) {
  2622. untagged_q = &ahc->untagged_queues[target];
  2623. if (TAILQ_FIRST(untagged_q) == NULL)
  2624. continue;
  2625. printf("Untagged Q(%d): ", target);
  2626. i = 0;
  2627. TAILQ_FOREACH(scb, untagged_q, links.tqe) {
  2628. if (i++ > 256)
  2629. break;
  2630. printf("%d ", scb->hscb->tag);
  2631. }
  2632. printf("n");
  2633. }
  2634. ahc_platform_dump_card_state(ahc);
  2635. ahc_outb(ahc, SCBPTR, saved_scbptr);
  2636. }
  2637. /************************* Target Mode ****************************************/
  2638. #ifdef AHC_TARGET_MODE
  2639. cam_status
  2640. ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
  2641.     struct ahc_tmode_tstate **tstate,
  2642.     struct ahc_tmode_lstate **lstate,
  2643.     int notfound_failure)
  2644. {
  2645. if ((ahc->features & AHC_TARGETMODE) == 0)
  2646. return (CAM_REQ_INVALID);
  2647. /*
  2648.  * Handle the 'black hole' device that sucks up
  2649.  * requests to unattached luns on enabled targets.
  2650.  */
  2651. if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
  2652.  && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
  2653. *tstate = NULL;
  2654. *lstate = ahc->black_hole;
  2655. } else {
  2656. u_int max_id;
  2657. max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
  2658. if (ccb->ccb_h.target_id > max_id)
  2659. return (CAM_TID_INVALID);
  2660. if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
  2661. return (CAM_LUN_INVALID);
  2662. *tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
  2663. *lstate = NULL;
  2664. if (*tstate != NULL)
  2665. *lstate =
  2666.     (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
  2667. }
  2668. if (notfound_failure != 0 && *lstate == NULL)
  2669. return (CAM_PATH_INVALID);
  2670. return (CAM_REQ_CMP);
  2671. }
  2672. void
  2673. ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
  2674. {
  2675. struct    ahc_tmode_tstate *tstate;
  2676. struct    ahc_tmode_lstate *lstate;
  2677. struct    ccb_en_lun *cel;
  2678. cam_status status;
  2679. u_int    target;
  2680. u_int    lun;
  2681. u_int    target_mask;
  2682. u_long    s;
  2683. char    channel;
  2684. status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
  2685.      /*notfound_failure*/FALSE);
  2686. if (status != CAM_REQ_CMP) {
  2687. ccb->ccb_h.status = status;
  2688. return;
  2689. }
  2690. if ((ahc->features & AHC_MULTIROLE) != 0) {
  2691. u_int    our_id;
  2692. if (cam_sim_bus(sim) == 0)
  2693. our_id = ahc->our_id;
  2694. else
  2695. our_id = ahc->our_id_b;
  2696. if (ccb->ccb_h.target_id != our_id) {
  2697. if ((ahc->features & AHC_MULTI_TID) != 0
  2698.      && (ahc->flags & AHC_INITIATORROLE) != 0) {
  2699. /*
  2700.  * Only allow additional targets if
  2701.  * the initiator role is disabled.
  2702.  * The hardware cannot handle a re-select-in
  2703.  * on the initiator id during a re-select-out
  2704.  * on a different target id.
  2705.  */
  2706. status = CAM_TID_INVALID;
  2707. } else if ((ahc->flags & AHC_INITIATORROLE) != 0
  2708. || ahc->enabled_luns > 0) {
  2709. /*
  2710.  * Only allow our target id to change
  2711.  * if the initiator role is not configured
  2712.  * and there are no enabled luns which
  2713.  * are attached to the currently registered
  2714.  * scsi id.
  2715.  */
  2716. status = CAM_TID_INVALID;
  2717. }
  2718. }
  2719. }
  2720. if (status != CAM_REQ_CMP) {
  2721. ccb->ccb_h.status = status;
  2722. return;
  2723. }
  2724. /*
  2725.  * We now have an id that is valid.
  2726.  * If we aren't in target mode, switch modes.
  2727.  */
  2728. if ((ahc->flags & AHC_TARGETROLE) == 0
  2729.  && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
  2730. u_long s;
  2731. printf("Configuring Target Moden");
  2732. ahc_lock(ahc, &s);
  2733. if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
  2734. ccb->ccb_h.status = CAM_BUSY;
  2735. ahc_unlock(ahc, &s);
  2736. return;
  2737. }
  2738. ahc->flags |= AHC_TARGETROLE;
  2739. if ((ahc->features & AHC_MULTIROLE) == 0)
  2740. ahc->flags &= ~AHC_INITIATORROLE;
  2741. ahc_pause(ahc);
  2742. ahc_loadseq(ahc);
  2743. ahc_unlock(ahc, &s);
  2744. }
  2745. cel = &ccb->cel;
  2746. target = ccb->ccb_h.target_id;
  2747. lun = ccb->ccb_h.target_lun;
  2748. channel = SIM_CHANNEL(ahc, sim);
  2749. target_mask = 0x01 << target;
  2750. if (channel == 'B')
  2751. target_mask <<= 8;
  2752. if (cel->enable != 0) {
  2753. u_int scsiseq;
  2754. /* Are we already enabled?? */
  2755. if (lstate != NULL) {
  2756. xpt_print_path(ccb->ccb_h.path);
  2757. printf("Lun already enabledn");
  2758. ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
  2759. return;
  2760. }
  2761. if (cel->grp6_len != 0
  2762.  || cel->grp7_len != 0) {
  2763. /*
  2764.  * Don't (yet?) support vendor
  2765.  * specific commands.
  2766.  */
  2767. ccb->ccb_h.status = CAM_REQ_INVALID;
  2768. printf("Non-zero Group Codesn");
  2769. return;
  2770. }
  2771. /*
  2772.  * Seems to be okay.
  2773.  * Setup our data structures.
  2774.  */
  2775. if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
  2776. tstate = ahc_alloc_tstate(ahc, target, channel);
  2777. if (tstate == NULL) {
  2778. xpt_print_path(ccb->ccb_h.path);
  2779. printf("Couldn't allocate tstaten");
  2780. ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
  2781. return;
  2782. }
  2783. }
  2784. lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT);
  2785. if (lstate == NULL) {
  2786. xpt_print_path(ccb->ccb_h.path);
  2787. printf("Couldn't allocate lstaten");
  2788. ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
  2789. return;
  2790. }
  2791. memset(lstate, 0, sizeof(*lstate));
  2792. status = xpt_create_path(&lstate->path, /*periph*/NULL,
  2793.  xpt_path_path_id(ccb->ccb_h.path),
  2794.  xpt_path_target_id(ccb->ccb_h.path),
  2795.  xpt_path_lun_id(ccb->ccb_h.path));
  2796. if (status != CAM_REQ_CMP) {
  2797. free(lstate, M_DEVBUF);
  2798. xpt_print_path(ccb->ccb_h.path);
  2799. printf("Couldn't allocate pathn");
  2800. ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
  2801. return;
  2802. }
  2803. SLIST_INIT(&lstate->accept_tios);
  2804. SLIST_INIT(&lstate->immed_notifies);
  2805. ahc_lock(ahc, &s);
  2806. ahc_pause(ahc);
  2807. if (target != CAM_TARGET_WILDCARD) {
  2808. tstate->enabled_luns[lun] = lstate;
  2809. ahc->enabled_luns++;
  2810. if ((ahc->features & AHC_MULTI_TID) != 0) {
  2811. u_int targid_mask;
  2812. targid_mask = ahc_inb(ahc, TARGID)
  2813.     | (ahc_inb(ahc, TARGID + 1) << 8);
  2814. targid_mask |= target_mask;
  2815. ahc_outb(ahc, TARGID, targid_mask);
  2816. ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
  2817. ahc_update_scsiid(ahc, targid_mask);
  2818. } else {
  2819. u_int our_id;
  2820. char  channel;
  2821. channel = SIM_CHANNEL(ahc, sim);
  2822. our_id = SIM_SCSI_ID(ahc, sim);
  2823. /*
  2824.  * This can only happen if selections
  2825.  * are not enabled
  2826.  */
  2827. if (target != our_id) {
  2828. u_int sblkctl;
  2829. char  cur_channel;
  2830. int   swap;
  2831. sblkctl = ahc_inb(ahc, SBLKCTL);
  2832. cur_channel = (sblkctl & SELBUSB)
  2833.     ? 'B' : 'A';
  2834. if ((ahc->features & AHC_TWIN) == 0)
  2835. cur_channel = 'A';
  2836. swap = cur_channel != channel;
  2837. if (channel == 'A')
  2838. ahc->our_id = target;
  2839. else
  2840. ahc->our_id_b = target;
  2841. if (swap)
  2842. ahc_outb(ahc, SBLKCTL,
  2843.  sblkctl ^ SELBUSB);
  2844. ahc_outb(ahc, SCSIID, target);
  2845. if (swap)
  2846. ahc_outb(ahc, SBLKCTL, sblkctl);
  2847. }
  2848. }
  2849. } else
  2850. ahc->black_hole = lstate;
  2851. /* Allow select-in operations */
  2852. if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
  2853. scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
  2854. scsiseq |= ENSELI;
  2855. ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
  2856. scsiseq = ahc_inb(ahc, SCSISEQ);
  2857. scsiseq |= ENSELI;
  2858. ahc_outb(ahc, SCSISEQ, scsiseq);
  2859. }
  2860. ahc_unpause(ahc);
  2861. ahc_unlock(ahc, &s);
  2862. ccb->ccb_h.status = CAM_REQ_CMP;
  2863. xpt_print_path(ccb->ccb_h.path);
  2864. printf("Lun now enabled for target moden");
  2865. } else {
  2866. struct scb *scb;
  2867. int i, empty;
  2868. if (lstate == NULL) {
  2869. ccb->ccb_h.status = CAM_LUN_INVALID;
  2870. return;
  2871. }
  2872. ahc_lock(ahc, &s);
  2873. ccb->ccb_h.status = CAM_REQ_CMP;
  2874. LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
  2875. struct ccb_hdr *ccbh;
  2876. ccbh = &scb->io_ctx->ccb_h;
  2877. if (ccbh->func_code == XPT_CONT_TARGET_IO
  2878.  && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
  2879. printf("CTIO pendingn");
  2880. ccb->ccb_h.status = CAM_REQ_INVALID;
  2881. ahc_unlock(ahc, &s);
  2882. return;
  2883. }
  2884. }
  2885. if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
  2886. printf("ATIOs pendingn");
  2887. ccb->ccb_h.status = CAM_REQ_INVALID;
  2888. }
  2889. if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
  2890. printf("INOTs pendingn");
  2891. ccb->ccb_h.status = CAM_REQ_INVALID;
  2892. }
  2893. if (ccb->ccb_h.status != CAM_REQ_CMP) {
  2894. ahc_unlock(ahc, &s);
  2895. return;
  2896. }
  2897. xpt_print_path(ccb->ccb_h.path);
  2898. printf("Target mode disabledn");
  2899. xpt_free_path(lstate->path);
  2900. free(lstate, M_DEVBUF);
  2901. ahc_pause(ahc);
  2902. /* Can we clean up the target too? */
  2903. if (target != CAM_TARGET_WILDCARD) {
  2904. tstate->enabled_luns[lun] = NULL;
  2905. ahc->enabled_luns--;
  2906. for (empty = 1, i = 0; i < 8; i++)
  2907. if (tstate->enabled_luns[i] != NULL) {
  2908. empty = 0;
  2909. break;
  2910. }
  2911. if (empty) {
  2912. ahc_free_tstate(ahc, target, channel,
  2913. /*force*/FALSE);
  2914. if (ahc->features & AHC_MULTI_TID) {
  2915. u_int targid_mask;
  2916. targid_mask = ahc_inb(ahc, TARGID)
  2917.     | (ahc_inb(ahc, TARGID + 1)
  2918.        << 8);
  2919. targid_mask &= ~target_mask;
  2920. ahc_outb(ahc, TARGID, targid_mask);
  2921. ahc_outb(ahc, TARGID+1,
  2922.    (targid_mask >> 8));
  2923. ahc_update_scsiid(ahc, targid_mask);
  2924. }
  2925. }
  2926. } else {
  2927. ahc->black_hole = NULL;
  2928. /*
  2929.  * We can't allow selections without
  2930.  * our black hole device.
  2931.  */
  2932. empty = TRUE;
  2933. }
  2934. if (ahc->enabled_luns == 0) {
  2935. /* Disallow select-in */
  2936. u_int scsiseq;
  2937. scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
  2938. scsiseq &= ~ENSELI;
  2939. ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
  2940. scsiseq = ahc_inb(ahc, SCSISEQ);
  2941. scsiseq &= ~ENSELI;
  2942. ahc_outb(ahc, SCSISEQ, scsiseq);
  2943. if ((ahc->features & AHC_MULTIROLE) == 0) {
  2944. printf("Configuring Initiator Moden");
  2945. ahc->flags &= ~AHC_TARGETROLE;
  2946. ahc->flags |= AHC_INITIATORROLE;
  2947. ahc_pause(ahc);
  2948. ahc_loadseq(ahc);
  2949. }
  2950. }
  2951. ahc_unpause(ahc);
  2952. ahc_unlock(ahc, &s);
  2953. }
  2954. }
  2955. static void
  2956. ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
  2957. {
  2958. u_int scsiid_mask;
  2959. u_int scsiid;
  2960. if ((ahc->features & AHC_MULTI_TID) == 0)
  2961. panic("ahc_update_scsiid called on non-multitid unitn");
  2962. /*
  2963.  * Since we will rely on the TARGID mask
  2964.  * for selection enables, ensure that OID
  2965.  * in SCSIID is not set to some other ID
  2966.  * that we don't want to allow selections on.
  2967.  */
  2968. if ((ahc->features & AHC_ULTRA2) != 0)
  2969. scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
  2970. else
  2971. scsiid = ahc_inb(ahc, SCSIID);
  2972. scsiid_mask = 0x1 << (scsiid & OID);
  2973. if ((targid_mask & scsiid_mask) == 0) {
  2974. u_int our_id;
  2975. /* ffs counts from 1 */
  2976. our_id = ffs(targid_mask);
  2977. if (our_id == 0)
  2978. our_id = ahc->our_id;
  2979. else
  2980. our_id--;
  2981. scsiid &= TID;
  2982. scsiid |= our_id;
  2983. }
  2984. if ((ahc->features & AHC_ULTRA2) != 0)
  2985. ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
  2986. else
  2987. ahc_outb(ahc, SCSIID, scsiid);
  2988. }
  2989. void
  2990. ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
  2991. {
  2992. struct target_cmd *cmd;
  2993. /*
  2994.  * If the card supports auto-access pause,
  2995.  * we can access the card directly regardless
  2996.  * of whether it is paused or not.
  2997.  */
  2998. if ((ahc->features & AHC_AUTOPAUSE) != 0)
  2999. paused = TRUE;
  3000. ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
  3001. while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
  3002. /*
  3003.  * Only advance through the queue if we
  3004.  * have the resources to process the command.
  3005.  */
  3006. if (ahc_handle_target_cmd(ahc, cmd) != 0)
  3007. break;
  3008. cmd->cmd_valid = 0;
  3009. ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
  3010. ahc->shared_data_dmamap,
  3011. ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
  3012. sizeof(struct target_cmd),
  3013. BUS_DMASYNC_PREREAD);
  3014. ahc->tqinfifonext++;
  3015. /*
  3016.  * Lazily update our position in the target mode incoming
  3017.  * command queue as seen by the sequencer.
  3018.  */
  3019. if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
  3020. if ((ahc->features & AHC_HS_MAILBOX) != 0) {
  3021. u_int hs_mailbox;
  3022. hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
  3023. hs_mailbox &= ~HOST_TQINPOS;
  3024. hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
  3025. ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
  3026. } else {
  3027. if (!paused)
  3028. ahc_pause(ahc);
  3029. ahc_outb(ahc, KERNEL_TQINPOS,
  3030.  ahc->tqinfifonext & HOST_TQINPOS);
  3031. if (!paused)
  3032. ahc_unpause(ahc);
  3033. }
  3034. }
  3035. }
  3036. }
  3037. static int
  3038. ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
  3039. {
  3040. struct   ahc_tmode_tstate *tstate;
  3041. struct   ahc_tmode_lstate *lstate;
  3042. struct   ccb_accept_tio *atio;
  3043. uint8_t *byte;
  3044. int   initiator;
  3045. int   target;
  3046. int   lun;
  3047. initiator = SCSIID_TARGET(ahc, cmd->scsiid);
  3048. target = SCSIID_OUR_ID(cmd->scsiid);
  3049. lun    = (cmd->identify & MSG_IDENTIFY_LUNMASK);
  3050. byte = cmd->bytes;
  3051. tstate = ahc->enabled_targets[target];
  3052. lstate = NULL;
  3053. if (tstate != NULL)
  3054. lstate = tstate->enabled_luns[lun];
  3055. /*
  3056.  * Commands for disabled luns go to the black hole driver.
  3057.  */
  3058. if (lstate == NULL)
  3059. lstate = ahc->black_hole;
  3060. atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
  3061. if (atio == NULL) {
  3062. ahc->flags |= AHC_TQINFIFO_BLOCKED;
  3063. /*
  3064.  * Wait for more ATIOs from the peripheral driver for this lun.
  3065.  */
  3066. if (bootverbose)
  3067. printf("%s: ATIOs exhaustedn", ahc_name(ahc));
  3068. return (1);
  3069. } else
  3070. ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
  3071. #if 0
  3072. printf("Incoming command from %d for %d:%d%sn",
  3073.        initiator, target, lun,
  3074.        lstate == ahc->black_hole ? "(Black Holed)" : "");
  3075. #endif
  3076. SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
  3077. if (lstate == ahc->black_hole) {
  3078. /* Fill in the wildcards */
  3079. atio->ccb_h.target_id = target;
  3080. atio->ccb_h.target_lun = lun;
  3081. }
  3082. /*
  3083.  * Package it up and send it off to
  3084.  * whomever has this lun enabled.
  3085.  */
  3086. atio->sense_len = 0;
  3087. atio->init_id = initiator;
  3088. if (byte[0] != 0xFF) {
  3089. /* Tag was included */
  3090. atio->tag_action = *byte++;
  3091. atio->tag_id = *byte++;
  3092. atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
  3093. } else {
  3094. atio->ccb_h.flags = 0;
  3095. }
  3096. byte++;
  3097. /* Okay.  Now determine the cdb size based on the command code */
  3098. switch (*byte >> CMD_GROUP_CODE_SHIFT) {
  3099. case 0:
  3100. atio->cdb_len = 6;
  3101. break;
  3102. case 1:
  3103. case 2:
  3104. atio->cdb_len = 10;
  3105. break;
  3106. case 4:
  3107. atio->cdb_len = 16;
  3108. break;
  3109. case 5:
  3110. atio->cdb_len = 12;
  3111. break;
  3112. case 3:
  3113. default:
  3114. /* Only copy the opcode. */
  3115. atio->cdb_len = 1;
  3116. printf("Reserved or VU command code type encounteredn");
  3117. break;
  3118. }
  3119. memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
  3120. atio->ccb_h.status |= CAM_CDB_RECVD;
  3121. if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
  3122. /*
  3123.  * We weren't allowed to disconnect.
  3124.  * We're hanging on the bus until a
  3125.  * continue target I/O comes in response
  3126.  * to this accept tio.
  3127.  */
  3128. #if 0
  3129. printf("Received Immediate Command %d:%d:%d - %pn",
  3130.        initiator, target, lun, ahc->pending_device);
  3131. #endif
  3132. ahc->pending_device = lstate;
  3133. ahc_freeze_ccb((union ccb *)atio);
  3134. atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
  3135. }
  3136. xpt_done((union ccb*)atio);
  3137. return (0);
  3138. }
  3139. #endif