Lines Matching +full:cmd +full:- +full:timeout +full:- +full:ms

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
120 ch->dev = dev; in mvs_ch_attach()
121 ch->unit = (intptr_t)device_get_ivars(dev); in mvs_ch_attach()
122 ch->quirks = ctlr->quirks; in mvs_ch_attach()
123 mtx_init(&ch->mtx, "MVS channel lock", NULL, MTX_DEF); in mvs_ch_attach()
124 ch->pm_level = 0; in mvs_ch_attach()
126 device_get_unit(dev), "pm_level", &ch->pm_level); in mvs_ch_attach()
127 if (ch->pm_level > 3) in mvs_ch_attach()
128 callout_init_mtx(&ch->pm_timer, &ch->mtx, 0); in mvs_ch_attach()
129 callout_init_mtx(&ch->reset_timer, &ch->mtx, 0); in mvs_ch_attach()
133 ch->user[i].revision = sata_rev; in mvs_ch_attach()
134 ch->user[i].mode = 0; in mvs_ch_attach()
135 ch->user[i].bytecount = (ch->quirks & MVS_Q_GENIIE) ? 8192 : 2048; in mvs_ch_attach()
136 ch->user[i].tags = MVS_MAX_SLOTS; in mvs_ch_attach()
137 ch->curr[i] = ch->user[i]; in mvs_ch_attach()
138 if (ch->pm_level) { in mvs_ch_attach()
139 ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ | in mvs_ch_attach()
143 ch->user[i].caps |= CTS_SATA_CAPS_H_AN; in mvs_ch_attach()
145 rid = ch->unit; in mvs_ch_attach()
146 if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in mvs_ch_attach()
152 mtx_lock(&ch->mtx); in mvs_ch_attach()
154 if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, in mvs_ch_attach()
160 if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL, in mvs_ch_attach()
161 mvs_ch_intr_locked, dev, &ch->ih))) { in mvs_ch_attach()
167 devq = cam_simq_alloc(MVS_MAX_SLOTS - 1); in mvs_ch_attach()
174 ch->sim = cam_sim_alloc(mvsaction, mvspoll, "mvsch", ch, in mvs_ch_attach()
175 device_get_unit(dev), &ch->mtx, in mvs_ch_attach()
176 2, (ch->quirks & MVS_Q_GENI) ? 0 : MVS_MAX_SLOTS - 1, in mvs_ch_attach()
178 if (ch->sim == NULL) { in mvs_ch_attach()
184 if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) { in mvs_ch_attach()
189 if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim), in mvs_ch_attach()
195 if (ch->pm_level > 3) { in mvs_ch_attach()
196 callout_reset(&ch->pm_timer, in mvs_ch_attach()
197 (ch->pm_level == 4) ? hz / 1000 : hz / 8, in mvs_ch_attach()
200 mtx_unlock(&ch->mtx); in mvs_ch_attach()
204 xpt_bus_deregister(cam_sim_path(ch->sim)); in mvs_ch_attach()
206 cam_sim_free(ch->sim, /*free_devq*/TRUE); in mvs_ch_attach()
208 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); in mvs_ch_attach()
210 bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); in mvs_ch_attach()
211 mtx_unlock(&ch->mtx); in mvs_ch_attach()
212 mtx_destroy(&ch->mtx); in mvs_ch_attach()
221 mtx_lock(&ch->mtx); in mvs_ch_detach()
222 xpt_async(AC_LOST_DEVICE, ch->path, NULL); in mvs_ch_detach()
224 if (ch->resetting) { in mvs_ch_detach()
225 ch->resetting = 0; in mvs_ch_detach()
226 xpt_release_simq(ch->sim, TRUE); in mvs_ch_detach()
228 xpt_free_path(ch->path); in mvs_ch_detach()
229 xpt_bus_deregister(cam_sim_path(ch->sim)); in mvs_ch_detach()
230 cam_sim_free(ch->sim, /*free_devq*/TRUE); in mvs_ch_detach()
231 mtx_unlock(&ch->mtx); in mvs_ch_detach()
233 if (ch->pm_level > 3) in mvs_ch_detach()
234 callout_drain(&ch->pm_timer); in mvs_ch_detach()
235 callout_drain(&ch->reset_timer); in mvs_ch_detach()
236 bus_teardown_intr(dev, ch->r_irq, ch->ih); in mvs_ch_detach()
237 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); in mvs_ch_detach()
243 bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem); in mvs_ch_detach()
244 mtx_destroy(&ch->mtx); in mvs_ch_detach()
255 ATA_OUTL(ch->r_mem, EDMA_IEM, 0); in mvs_ch_init()
257 ch->curr_mode = MVS_EDMA_UNKNOWN; in mvs_ch_init()
260 ATA_OUTL(ch->r_mem, SATA_FISIC, 0); in mvs_ch_init()
261 reg = ATA_INL(ch->r_mem, SATA_FISC); in mvs_ch_init()
263 ATA_OUTL(ch->r_mem, SATA_FISC, reg); in mvs_ch_init()
264 reg = ATA_INL(ch->r_mem, SATA_FISIM); in mvs_ch_init()
266 ATA_OUTL(ch->r_mem, SATA_FISC, reg); in mvs_ch_init()
268 ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff); in mvs_ch_init()
270 ATA_OUTL(ch->r_mem, EDMA_IEC, 0); in mvs_ch_init()
272 ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT); in mvs_ch_init()
284 ATA_OUTL(ch->r_mem, EDMA_IEM, 0); in mvs_ch_deinit()
293 mtx_lock(&ch->mtx); in mvs_ch_suspend()
294 xpt_freeze_simq(ch->sim, 1); in mvs_ch_suspend()
295 while (ch->oslots) in mvs_ch_suspend()
296 msleep(ch, &ch->mtx, PRIBIO, "mvssusp", hz/100); in mvs_ch_suspend()
298 if (ch->resetting) { in mvs_ch_suspend()
299 ch->resetting = 0; in mvs_ch_suspend()
300 callout_stop(&ch->reset_timer); in mvs_ch_suspend()
301 xpt_release_simq(ch->sim, TRUE); in mvs_ch_suspend()
304 mtx_unlock(&ch->mtx); in mvs_ch_suspend()
313 mtx_lock(&ch->mtx); in mvs_ch_resume()
316 xpt_release_simq(ch->sim, TRUE); in mvs_ch_resume()
317 mtx_unlock(&ch->mtx); in mvs_ch_resume()
336 0, NULL, NULL, &ch->dma.workrq_tag)) in mvs_dmainit()
338 if (bus_dmamem_alloc(ch->dma.workrq_tag, (void **)&ch->dma.workrq, 0, in mvs_dmainit()
339 &ch->dma.workrq_map)) in mvs_dmainit()
341 if (bus_dmamap_load(ch->dma.workrq_tag, ch->dma.workrq_map, in mvs_dmainit()
342 ch->dma.workrq, MVS_WORKRQ_SIZE, mvs_dmasetupc_cb, &dcba, 0) || in mvs_dmainit()
344 bus_dmamem_free(ch->dma.workrq_tag, in mvs_dmainit()
345 ch->dma.workrq, ch->dma.workrq_map); in mvs_dmainit()
348 ch->dma.workrq_bus = dcba.maddr; in mvs_dmainit()
353 0, NULL, NULL, &ch->dma.workrp_tag)) in mvs_dmainit()
355 if (bus_dmamem_alloc(ch->dma.workrp_tag, (void **)&ch->dma.workrp, 0, in mvs_dmainit()
356 &ch->dma.workrp_map)) in mvs_dmainit()
358 if (bus_dmamap_load(ch->dma.workrp_tag, ch->dma.workrp_map, in mvs_dmainit()
359 ch->dma.workrp, MVS_WORKRP_SIZE, mvs_dmasetupc_cb, &dcba, 0) || in mvs_dmainit()
361 bus_dmamem_free(ch->dma.workrp_tag, in mvs_dmainit()
362 ch->dma.workrp, ch->dma.workrp_map); in mvs_dmainit()
365 ch->dma.workrp_bus = dcba.maddr; in mvs_dmainit()
371 0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) { in mvs_dmainit()
377 device_printf(dev, "WARNING - DMA initialization failed\n"); in mvs_dmainit()
386 if (!(dcba->error = error)) in mvs_dmasetupc_cb()
387 dcba->maddr = segs[0].ds_addr; in mvs_dmasetupc_cb()
395 if (ch->dma.data_tag) { in mvs_dmafini()
396 bus_dma_tag_destroy(ch->dma.data_tag); in mvs_dmafini()
397 ch->dma.data_tag = NULL; in mvs_dmafini()
399 if (ch->dma.workrp_bus) { in mvs_dmafini()
400 bus_dmamap_unload(ch->dma.workrp_tag, ch->dma.workrp_map); in mvs_dmafini()
401 bus_dmamem_free(ch->dma.workrp_tag, in mvs_dmafini()
402 ch->dma.workrp, ch->dma.workrp_map); in mvs_dmafini()
403 ch->dma.workrp_bus = 0; in mvs_dmafini()
404 ch->dma.workrp = NULL; in mvs_dmafini()
406 if (ch->dma.workrp_tag) { in mvs_dmafini()
407 bus_dma_tag_destroy(ch->dma.workrp_tag); in mvs_dmafini()
408 ch->dma.workrp_tag = NULL; in mvs_dmafini()
410 if (ch->dma.workrq_bus) { in mvs_dmafini()
411 bus_dmamap_unload(ch->dma.workrq_tag, ch->dma.workrq_map); in mvs_dmafini()
412 bus_dmamem_free(ch->dma.workrq_tag, in mvs_dmafini()
413 ch->dma.workrq, ch->dma.workrq_map); in mvs_dmafini()
414 ch->dma.workrq_bus = 0; in mvs_dmafini()
415 ch->dma.workrq = NULL; in mvs_dmafini()
417 if (ch->dma.workrq_tag) { in mvs_dmafini()
418 bus_dma_tag_destroy(ch->dma.workrq_tag); in mvs_dmafini()
419 ch->dma.workrq_tag = NULL; in mvs_dmafini()
430 bzero(ch->slot, sizeof(ch->slot)); in mvs_slotsalloc()
432 struct mvs_slot *slot = &ch->slot[i]; in mvs_slotsalloc()
434 slot->dev = dev; in mvs_slotsalloc()
435 slot->slot = i; in mvs_slotsalloc()
436 slot->state = MVS_SLOT_EMPTY; in mvs_slotsalloc()
437 slot->eprd_offset = MVS_EPRD_OFFSET + MVS_EPRD_SIZE * i; in mvs_slotsalloc()
438 slot->ccb = NULL; in mvs_slotsalloc()
439 callout_init_mtx(&slot->timeout, &ch->mtx, 0); in mvs_slotsalloc()
441 if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map)) in mvs_slotsalloc()
442 device_printf(ch->dev, "FAILURE - create data_map\n"); in mvs_slotsalloc()
454 struct mvs_slot *slot = &ch->slot[i]; in mvs_slotsfree()
456 callout_drain(&slot->timeout); in mvs_slotsfree()
457 if (slot->dma.data_map) { in mvs_slotsfree()
458 bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); in mvs_slotsfree()
459 slot->dma.data_map = NULL; in mvs_slotsfree()
471 work = ch->dma.workrq_bus; in mvs_setup_edma_queues()
472 ATA_OUTL(ch->r_mem, EDMA_REQQBAH, work >> 32); in mvs_setup_edma_queues()
473 ATA_OUTL(ch->r_mem, EDMA_REQQIP, work & 0xffffffff); in mvs_setup_edma_queues()
474 ATA_OUTL(ch->r_mem, EDMA_REQQOP, work & 0xffffffff); in mvs_setup_edma_queues()
475 bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map, in mvs_setup_edma_queues()
478 memset(ch->dma.workrp, 0xff, MVS_WORKRP_SIZE); in mvs_setup_edma_queues()
479 work = ch->dma.workrp_bus; in mvs_setup_edma_queues()
480 ATA_OUTL(ch->r_mem, EDMA_RESQBAH, work >> 32); in mvs_setup_edma_queues()
481 ATA_OUTL(ch->r_mem, EDMA_RESQIP, work & 0xffffffff); in mvs_setup_edma_queues()
482 ATA_OUTL(ch->r_mem, EDMA_RESQOP, work & 0xffffffff); in mvs_setup_edma_queues()
483 bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map, in mvs_setup_edma_queues()
485 ch->out_idx = 0; in mvs_setup_edma_queues()
486 ch->in_idx = 0; in mvs_setup_edma_queues()
493 int timeout; in mvs_set_edma_mode() local
496 if (mode == ch->curr_mode) in mvs_set_edma_mode()
499 if (ch->curr_mode != MVS_EDMA_OFF) { in mvs_set_edma_mode()
500 ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EDSEDMA); in mvs_set_edma_mode()
501 timeout = 0; in mvs_set_edma_mode()
502 while (ATA_INL(ch->r_mem, EDMA_CMD) & EDMA_CMD_EENEDMA) { in mvs_set_edma_mode()
504 if (timeout++ > 1000) { in mvs_set_edma_mode()
510 ch->curr_mode = mode; in mvs_set_edma_mode()
511 ch->fbs_enabled = 0; in mvs_set_edma_mode()
512 ch->fake_busy = 0; in mvs_set_edma_mode()
517 if (ch->pm_present) { in mvs_set_edma_mode()
519 if (ch->quirks & MVS_Q_GENIIE) { in mvs_set_edma_mode()
521 ch->fbs_enabled = 1; in mvs_set_edma_mode()
524 if (ch->quirks & MVS_Q_GENI) in mvs_set_edma_mode()
526 else if (ch->quirks & MVS_Q_GENII) in mvs_set_edma_mode()
528 if (ch->quirks & MVS_Q_CT) in mvs_set_edma_mode()
536 ATA_OUTL(ch->r_mem, EDMA_CFG, ecfg); in mvs_set_edma_mode()
538 if (ch->quirks & MVS_Q_GENIIE) { in mvs_set_edma_mode()
539 /* Configure FBS-related registers */ in mvs_set_edma_mode()
540 fcfg = ATA_INL(ch->r_mem, SATA_FISC); in mvs_set_edma_mode()
541 ltm = ATA_INL(ch->r_mem, SATA_LTM); in mvs_set_edma_mode()
542 hc = ATA_INL(ch->r_mem, EDMA_HC); in mvs_set_edma_mode()
543 if (ch->fbs_enabled) { in mvs_set_edma_mode()
559 ATA_OUTL(ch->r_mem, SATA_FISC, fcfg); in mvs_set_edma_mode()
560 ATA_OUTL(ch->r_mem, SATA_LTM, ltm); in mvs_set_edma_mode()
561 ATA_OUTL(ch->r_mem, EDMA_HC, hc); in mvs_set_edma_mode()
564 unkn = ATA_INL(ch->r_mem, EDMA_UNKN_RESD); in mvs_set_edma_mode()
569 ATA_OUTL(ch->r_mem, EDMA_UNKN_RESD, unkn); in mvs_set_edma_mode()
573 ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EENEDMA); in mvs_set_edma_mode()
597 if (ch->pm_level == 0) { in mvs_phy_check_events()
598 u_int32_t status = ATA_INL(ch->r_mem, SATA_SS); in mvs_phy_check_events()
612 if (xpt_create_path(&ccb->ccb_h.path, NULL, in mvs_phy_check_events()
613 cam_sim_path(ch->sim), in mvs_phy_check_events()
630 /* Try to read PMP field from SDB FIS. Present only for Gen-IIe. */ in mvs_notify_events()
631 fis = ATA_INL(ch->r_mem, SATA_FISDW0); in mvs_notify_events()
635 d = ch->pm_present ? 15 : 0; in mvs_notify_events()
639 xpt_path_path_id(ch->path), d, 0) == CAM_REQ_CMP) { in mvs_notify_events()
649 device_t dev = (device_t)arg->arg; in mvs_ch_intr_locked()
652 mtx_lock(&ch->mtx); in mvs_ch_intr_locked()
654 mtx_unlock(&ch->mtx); in mvs_ch_intr_locked()
664 if (ch->numrslots != 0) in mvs_ch_pm()
666 /* If we are idle - request power state transition. */ in mvs_ch_pm()
667 work = ATA_INL(ch->r_mem, SATA_SC); in mvs_ch_pm()
669 if (ch->pm_level == 4) in mvs_ch_pm()
673 ATA_OUTL(ch->r_mem, SATA_SC, work); in mvs_ch_pm()
681 int timeout = 0; in mvs_ch_pm_wake() local
683 work = ATA_INL(ch->r_mem, SATA_SS); in mvs_ch_pm_wake()
686 /* If we are not in active state - request power state transition. */ in mvs_ch_pm_wake()
687 work = ATA_INL(ch->r_mem, SATA_SC); in mvs_ch_pm_wake()
690 ATA_OUTL(ch->r_mem, SATA_SC, work); in mvs_ch_pm_wake()
692 while ((ATA_INL(ch->r_mem, SATA_SS) & SATA_SS_IPM_ACTIVE) == 0 && in mvs_ch_pm_wake()
693 timeout++ < 100) { in mvs_ch_pm_wake()
702 device_t dev = (device_t)arg->arg; in mvs_ch_intr()
706 int i, ccs, port = -1, selfdis = 0; in mvs_ch_intr()
707 int edma = (ch->numtslots != 0 || ch->numdslots != 0); in mvs_ch_intr()
710 if ((arg->cause & 2) && edma) in mvs_ch_intr()
713 if (arg->cause & 1) { in mvs_ch_intr()
714 iec = ATA_INL(ch->r_mem, EDMA_IEC); in mvs_ch_intr()
716 serr = ATA_INL(ch->r_mem, SATA_SE); in mvs_ch_intr()
717 ATA_OUTL(ch->r_mem, SATA_SE, serr); in mvs_ch_intr()
719 /* EDMA self-disabled due to error. */ in mvs_ch_intr()
724 /* For Gen-I this bit means self-disable. */ in mvs_ch_intr()
725 if (ch->quirks & MVS_Q_GENI) in mvs_ch_intr()
727 /* For Gen-II this bit means SDB-N. */ in mvs_ch_intr()
728 else if (ch->quirks & MVS_Q_GENII) in mvs_ch_intr()
730 else /* For Gen-IIe - read FIS interrupt cause. */ in mvs_ch_intr()
731 fisic = ATA_INL(ch->r_mem, SATA_FISIC); in mvs_ch_intr()
734 ch->curr_mode = MVS_EDMA_UNKNOWN; in mvs_ch_intr()
735 ATA_OUTL(ch->r_mem, EDMA_IEC, ~iec); in mvs_ch_intr()
738 port = -1; in mvs_ch_intr()
739 if (ch->numpslots != 0) { in mvs_ch_intr()
742 if (ch->quirks & MVS_Q_GENIIE) in mvs_ch_intr()
743 ccs = EDMA_S_EIOID(ATA_INL(ch->r_mem, EDMA_S)); in mvs_ch_intr()
745 ccs = EDMA_S_EDEVQUETAG(ATA_INL(ch->r_mem, EDMA_S)); in mvs_ch_intr()
746 /* Check if error is one-PMP-port-specific, */ in mvs_ch_intr()
747 if (ch->fbs_enabled) { in mvs_ch_intr()
750 if (ch->numrslotspd[i] == 0) in mvs_ch_intr()
752 if (port == -1) in mvs_ch_intr()
755 port = -2; in mvs_ch_intr()
759 /* If several ports were active and EDMA still enabled - in mvs_ch_intr()
762 if (port == -2 && !selfdis) { in mvs_ch_intr()
763 uint16_t p = ATA_INL(ch->r_mem, SATA_SATAITC) >> 16; in mvs_ch_intr()
764 port = ffs(p) - 1; in mvs_ch_intr()
765 if (port != (fls(p) - 1)) in mvs_ch_intr()
766 port = -2; in mvs_ch_intr()
773 if (((ch->rslots >> i) & 1) == 0) in mvs_ch_intr()
776 ch->slot[i].ccb->ccb_h.target_id != port) in mvs_ch_intr()
779 if (port != -2) { in mvs_ch_intr()
780 if (ch->numtslots == 0) { in mvs_ch_intr()
792 ch->fatalerr = 1; in mvs_ch_intr()
795 if (ch->numtslots == 0 && in mvs_ch_intr()
796 i != ccs && port != -2) in mvs_ch_intr()
802 mvs_end_transaction(&ch->slot[i], et); in mvs_ch_intr()
805 /* Process SDB-N. */ in mvs_ch_intr()
809 ATA_OUTL(ch->r_mem, SATA_FISIC, ~fisic); in mvs_ch_intr()
810 /* Process hot-plug. */ in mvs_ch_intr()
816 if ((arg->cause & 2) && !edma) in mvs_ch_intr()
817 mvs_legacy_intr(dev, arg->cause & 4); in mvs_ch_intr()
824 uint8_t status = ATA_INB(ch->r_mem, clear ? ATA_STATUS : ATA_ALTSTAT); in mvs_getstatus()
826 if (ch->fake_busy) { in mvs_getstatus()
828 ch->fake_busy = 0; in mvs_getstatus()
839 struct mvs_slot *slot = &ch->slot[0]; /* PIO is always in slot 0. */ in mvs_legacy_intr()
840 union ccb *ccb = slot->ccb; in mvs_legacy_intr()
848 if (slot->state < MVS_SLOT_RUNNING) in mvs_legacy_intr()
866 if (ccb->ccb_h.func_code == XPT_ATA_IO) { /* ATA PIO */ in mvs_legacy_intr()
867 ccb->ataio.res.status = status; in mvs_legacy_intr()
869 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in mvs_legacy_intr()
870 /* If data read command - get them. */ in mvs_legacy_intr()
871 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { in mvs_legacy_intr()
873 device_printf(dev, "timeout waiting for read DRQ\n"); in mvs_legacy_intr()
875 xpt_freeze_simq(ch->sim, 1); in mvs_legacy_intr()
876 ch->toslots |= (1 << slot->slot); in mvs_legacy_intr()
879 ATA_INSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
880 (uint16_t *)(ccb->ataio.data_ptr + ch->donecount), in mvs_legacy_intr()
881 ch->transfersize / 2); in mvs_legacy_intr()
884 ch->donecount += ch->transfersize; in mvs_legacy_intr()
886 if (ccb->ataio.dxfer_len > ch->donecount) { in mvs_legacy_intr()
888 ch->transfersize = min(ccb->ataio.dxfer_len - ch->donecount, in mvs_legacy_intr()
889 ch->transfersize); in mvs_legacy_intr()
890 /* If data write command - put them */ in mvs_legacy_intr()
891 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { in mvs_legacy_intr()
894 "timeout waiting for write DRQ\n"); in mvs_legacy_intr()
896 xpt_freeze_simq(ch->sim, 1); in mvs_legacy_intr()
897 ch->toslots |= (1 << slot->slot); in mvs_legacy_intr()
900 ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
901 (uint16_t *)(ccb->ataio.data_ptr + ch->donecount), in mvs_legacy_intr()
902 ch->transfersize / 2); in mvs_legacy_intr()
906 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) in mvs_legacy_intr()
910 } else if (ch->basic_dma) { /* ATAPI DMA */ in mvs_legacy_intr()
913 else if (ATA_INL(ch->r_mem, DMA_S) & DMA_S_ERR) in mvs_legacy_intr()
916 ATA_OUTL(ch->r_mem, DMA_C, 0); in mvs_legacy_intr()
919 length = ATA_INB(ch->r_mem,ATA_CYL_LSB) | in mvs_legacy_intr()
920 (ATA_INB(ch->r_mem,ATA_CYL_MSB) << 8); in mvs_legacy_intr()
921 size = min(ch->transfersize, length); in mvs_legacy_intr()
922 ireason = ATA_INB(ch->r_mem,ATA_IREASON); in mvs_legacy_intr()
931 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { in mvs_legacy_intr()
937 ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
938 (uint16_t *)(ccb->csio.data_ptr + ch->donecount), in mvs_legacy_intr()
940 for (resid = ch->transfersize + (size & 1); in mvs_legacy_intr()
942 ATA_OUTW(ch->r_mem, ATA_DATA, 0); in mvs_legacy_intr()
943 ch->donecount += length; in mvs_legacy_intr()
945 ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount, in mvs_legacy_intr()
946 ch->curr[ccb->ccb_h.target_id].bytecount); in mvs_legacy_intr()
951 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { in mvs_legacy_intr()
957 ATA_INSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
958 (uint16_t *)(ccb->csio.data_ptr + ch->donecount), in mvs_legacy_intr()
962 ATA_INSW_STRM(ch->r_mem, ATA_DATA, (void*)buf, 1); in mvs_legacy_intr()
963 ((uint8_t *)ccb->csio.data_ptr + ch->donecount + in mvs_legacy_intr()
966 for (resid = ch->transfersize + (size & 1); in mvs_legacy_intr()
968 ATA_INW(ch->r_mem, ATA_DATA); in mvs_legacy_intr()
969 ch->donecount += length; in mvs_legacy_intr()
971 ch->transfersize = min(ccb->csio.dxfer_len - ch->donecount, in mvs_legacy_intr()
972 ch->curr[ccb->ccb_h.target_id].bytecount); in mvs_legacy_intr()
978 "WARNING - DONEDRQ non conformant device\n"); in mvs_legacy_intr()
979 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { in mvs_legacy_intr()
980 ATA_INSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
981 (uint16_t *)(ccb->csio.data_ptr + ch->donecount), in mvs_legacy_intr()
983 ch->donecount += length; in mvs_legacy_intr()
985 else if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { in mvs_legacy_intr()
986 ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_intr()
987 (uint16_t *)(ccb->csio.data_ptr + ch->donecount), in mvs_legacy_intr()
989 ch->donecount += length; in mvs_legacy_intr()
1023 val = ATA_INL(ch->r_mem, EDMA_RESQIP); in mvs_crbq_intr()
1025 val = ATA_INL(ch->r_mem, EDMA_RESQIP); in mvs_crbq_intr()
1028 bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map, in mvs_crbq_intr()
1030 fin_idx = cin_idx = ch->in_idx; in mvs_crbq_intr()
1031 ch->in_idx = in_idx; in mvs_crbq_intr()
1034 (ch->dma.workrp + MVS_CRPB_OFFSET + in mvs_crbq_intr()
1036 slot = le16toh(crpb->id) & MVS_CRPB_TAG_MASK; in mvs_crbq_intr()
1037 flags = le16toh(crpb->rspflg); in mvs_crbq_intr()
1043 if (crpb->id == 0xffff && crpb->rspflg == 0xffff) { in mvs_crbq_intr()
1045 "%d (%d->%d) tag %d flags %04x rs %08x\n", in mvs_crbq_intr()
1046 cin_idx, fin_idx, in_idx, slot, flags, ch->rslots); in mvs_crbq_intr()
1049 if (ch->numtslots != 0 || in mvs_crbq_intr()
1052 crpb->id = 0xffff; in mvs_crbq_intr()
1053 crpb->rspflg = 0xffff; in mvs_crbq_intr()
1055 if (ch->slot[slot].state >= MVS_SLOT_RUNNING) { in mvs_crbq_intr()
1056 ccb = ch->slot[slot].ccb; in mvs_crbq_intr()
1057 ccb->ataio.res.status = in mvs_crbq_intr()
1060 mvs_end_transaction(&ch->slot[slot], MVS_ERR_NONE); in mvs_crbq_intr()
1063 "%d (%d->%d) tag %d flags %04x rs %08x\n", in mvs_crbq_intr()
1065 ch->rslots); in mvs_crbq_intr()
1072 cin_idx = (cin_idx + 1) & (MVS_MAX_SLOTS - 1); in mvs_crbq_intr()
1074 bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map, in mvs_crbq_intr()
1076 if (cin_idx == ch->in_idx) { in mvs_crbq_intr()
1077 ATA_OUTL(ch->r_mem, EDMA_RESQOP, in mvs_crbq_intr()
1078 ch->dma.workrp_bus | (cin_idx << EDMA_RESQP_ERPQP_SHIFT)); in mvs_crbq_intr()
1088 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in mvs_check_collision()
1090 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_check_collision()
1091 /* Can't mix NCQ and non-NCQ DMA commands. */ in mvs_check_collision()
1092 if (ch->numdslots != 0) in mvs_check_collision()
1095 if (ch->numpslots != 0) in mvs_check_collision()
1098 if (!ch->fbs_enabled) { in mvs_check_collision()
1100 if (ch->numtslots != 0 && in mvs_check_collision()
1101 ch->taggedtarget != ccb->ccb_h.target_id) in mvs_check_collision()
1104 /* Non-NCQ DMA */ in mvs_check_collision()
1105 } else if (ccb->ataio.cmd.flags & CAM_ATAIO_DMA) { in mvs_check_collision()
1106 /* Can't mix non-NCQ DMA and NCQ commands. */ in mvs_check_collision()
1107 if (ch->numtslots != 0) in mvs_check_collision()
1109 /* Can't mix non-NCQ DMA and PIO commands. */ in mvs_check_collision()
1110 if (ch->numpslots != 0) in mvs_check_collision()
1115 if (ch->numrslots != 0) in mvs_check_collision()
1118 if (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)) { in mvs_check_collision()
1120 if (ch->numrslots != 0) in mvs_check_collision()
1125 if (ch->numrslots != 0) in mvs_check_collision()
1129 if (ch->aslots != 0) in mvs_check_collision()
1138 struct ata_res *res = &ccb->ataio.res; in mvs_tfd_read()
1140 res->status = ATA_INB(ch->r_mem, ATA_ALTSTAT); in mvs_tfd_read()
1141 res->error = ATA_INB(ch->r_mem, ATA_ERROR); in mvs_tfd_read()
1142 res->device = ATA_INB(ch->r_mem, ATA_DRIVE); in mvs_tfd_read()
1143 ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_HOB); in mvs_tfd_read()
1144 res->sector_count_exp = ATA_INB(ch->r_mem, ATA_COUNT); in mvs_tfd_read()
1145 res->lba_low_exp = ATA_INB(ch->r_mem, ATA_SECTOR); in mvs_tfd_read()
1146 res->lba_mid_exp = ATA_INB(ch->r_mem, ATA_CYL_LSB); in mvs_tfd_read()
1147 res->lba_high_exp = ATA_INB(ch->r_mem, ATA_CYL_MSB); in mvs_tfd_read()
1148 ATA_OUTB(ch->r_mem, ATA_CONTROL, 0); in mvs_tfd_read()
1149 res->sector_count = ATA_INB(ch->r_mem, ATA_COUNT); in mvs_tfd_read()
1150 res->lba_low = ATA_INB(ch->r_mem, ATA_SECTOR); in mvs_tfd_read()
1151 res->lba_mid = ATA_INB(ch->r_mem, ATA_CYL_LSB); in mvs_tfd_read()
1152 res->lba_high = ATA_INB(ch->r_mem, ATA_CYL_MSB); in mvs_tfd_read()
1159 struct ata_cmd *cmd = &ccb->ataio.cmd; in mvs_tfd_write() local
1161 ATA_OUTB(ch->r_mem, ATA_DRIVE, cmd->device); in mvs_tfd_write()
1162 ATA_OUTB(ch->r_mem, ATA_CONTROL, cmd->control); in mvs_tfd_write()
1163 ATA_OUTB(ch->r_mem, ATA_FEATURE, cmd->features_exp); in mvs_tfd_write()
1164 ATA_OUTB(ch->r_mem, ATA_FEATURE, cmd->features); in mvs_tfd_write()
1165 ATA_OUTB(ch->r_mem, ATA_COUNT, cmd->sector_count_exp); in mvs_tfd_write()
1166 ATA_OUTB(ch->r_mem, ATA_COUNT, cmd->sector_count); in mvs_tfd_write()
1167 ATA_OUTB(ch->r_mem, ATA_SECTOR, cmd->lba_low_exp); in mvs_tfd_write()
1168 ATA_OUTB(ch->r_mem, ATA_SECTOR, cmd->lba_low); in mvs_tfd_write()
1169 ATA_OUTB(ch->r_mem, ATA_CYL_LSB, cmd->lba_mid_exp); in mvs_tfd_write()
1170 ATA_OUTB(ch->r_mem, ATA_CYL_LSB, cmd->lba_mid); in mvs_tfd_write()
1171 ATA_OUTB(ch->r_mem, ATA_CYL_MSB, cmd->lba_high_exp); in mvs_tfd_write()
1172 ATA_OUTB(ch->r_mem, ATA_CYL_MSB, cmd->lba_high); in mvs_tfd_write()
1173 ATA_OUTB(ch->r_mem, ATA_COMMAND, cmd->command); in mvs_tfd_write()
1184 if (ch->pm_level > 0) in mvs_begin_transaction()
1187 if (ccb->ccb_h.func_code == XPT_ATA_IO && in mvs_begin_transaction()
1188 (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { in mvs_begin_transaction()
1193 slotn = ffs(~ch->oslots) - 1; in mvs_begin_transaction()
1194 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in mvs_begin_transaction()
1195 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { in mvs_begin_transaction()
1196 if (ch->quirks & MVS_Q_GENIIE) in mvs_begin_transaction()
1197 tag = ffs(~ch->otagspd[ccb->ccb_h.target_id]) - 1; in mvs_begin_transaction()
1203 slot = &ch->slot[slotn]; in mvs_begin_transaction()
1204 slot->ccb = ccb; in mvs_begin_transaction()
1205 slot->tag = tag; in mvs_begin_transaction()
1207 if (ch->numrslots == 0 && ch->pm_level > 3) in mvs_begin_transaction()
1208 callout_stop(&ch->pm_timer); in mvs_begin_transaction()
1210 ch->oslots |= (1 << slot->slot); in mvs_begin_transaction()
1211 ch->numrslots++; in mvs_begin_transaction()
1212 ch->numrslotspd[ccb->ccb_h.target_id]++; in mvs_begin_transaction()
1213 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in mvs_begin_transaction()
1214 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_begin_transaction()
1215 ch->otagspd[ccb->ccb_h.target_id] |= (1 << slot->tag); in mvs_begin_transaction()
1216 ch->numtslots++; in mvs_begin_transaction()
1217 ch->numtslotspd[ccb->ccb_h.target_id]++; in mvs_begin_transaction()
1218 ch->taggedtarget = ccb->ccb_h.target_id; in mvs_begin_transaction()
1220 } else if (ccb->ataio.cmd.flags & CAM_ATAIO_DMA) { in mvs_begin_transaction()
1221 ch->numdslots++; in mvs_begin_transaction()
1224 ch->numpslots++; in mvs_begin_transaction()
1227 if (ccb->ataio.cmd.flags & in mvs_begin_transaction()
1229 ch->aslots |= (1 << slot->slot); in mvs_begin_transaction()
1232 uint8_t *cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ? in mvs_begin_transaction()
1233 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes; in mvs_begin_transaction()
1234 ch->numpslots++; in mvs_begin_transaction()
1235 /* Use ATAPI DMA only for commands without under-/overruns. */ in mvs_begin_transaction()
1236 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && in mvs_begin_transaction()
1237 ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA && in mvs_begin_transaction()
1238 (ch->quirks & MVS_Q_SOC) == 0 && in mvs_begin_transaction()
1248 ch->basic_dma = 1; in mvs_begin_transaction()
1252 if (ch->numpslots == 0 || ch->basic_dma) { in mvs_begin_transaction()
1253 slot->state = MVS_SLOT_LOADING; in mvs_begin_transaction()
1254 bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, in mvs_begin_transaction()
1265 struct mvs_channel *ch = device_get_softc(slot->dev); in mvs_dmasetprd()
1270 device_printf(slot->dev, "DMA load error\n"); in mvs_dmasetprd()
1275 /* If there is only one segment - no need to use S/G table on Gen-IIe. */ in mvs_dmasetprd()
1276 if (nsegs == 1 && ch->basic_dma == 0 && (ch->quirks & MVS_Q_GENIIE)) { in mvs_dmasetprd()
1277 slot->dma.addr = segs[0].ds_addr; in mvs_dmasetprd()
1278 slot->dma.len = segs[0].ds_len; in mvs_dmasetprd()
1280 slot->dma.addr = 0; in mvs_dmasetprd()
1282 eprd = (struct mvs_eprd *)(ch->dma.workrq + slot->eprd_offset); in mvs_dmasetprd()
1289 eprd[i - 1].bytecount |= htole32(MVS_EPRD_EOF); in mvs_dmasetprd()
1291 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, in mvs_dmasetprd()
1292 ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ? in mvs_dmasetprd()
1294 if (ch->basic_dma) in mvs_dmasetprd()
1303 device_t dev = slot->dev; in mvs_legacy_execute_transaction()
1306 union ccb *ccb = slot->ccb; in mvs_legacy_execute_transaction()
1307 int port = ccb->ccb_h.target_id & 0x0f; in mvs_legacy_execute_transaction()
1308 int timeout; in mvs_legacy_execute_transaction() local
1310 slot->state = MVS_SLOT_RUNNING; in mvs_legacy_execute_transaction()
1311 ch->rslots |= (1 << slot->slot); in mvs_legacy_execute_transaction()
1312 ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT); in mvs_legacy_execute_transaction()
1313 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in mvs_legacy_execute_transaction()
1316 if (ccb->ataio.cmd.command == ATA_DEVICE_RESET) { in mvs_legacy_execute_transaction()
1317 int timeout = 1000000; in mvs_legacy_execute_transaction() local
1320 ccb->ataio.res.status = ATA_INB(ch->r_mem, ATA_STATUS); in mvs_legacy_execute_transaction()
1321 } while (ccb->ataio.res.status & ATA_S_BUSY && timeout--); in mvs_legacy_execute_transaction()
1325 ch->donecount = 0; in mvs_legacy_execute_transaction()
1326 if (ccb->ataio.cmd.command == ATA_READ_MUL || in mvs_legacy_execute_transaction()
1327 ccb->ataio.cmd.command == ATA_READ_MUL48 || in mvs_legacy_execute_transaction()
1328 ccb->ataio.cmd.command == ATA_WRITE_MUL || in mvs_legacy_execute_transaction()
1329 ccb->ataio.cmd.command == ATA_WRITE_MUL48) { in mvs_legacy_execute_transaction()
1330 ch->transfersize = min(ccb->ataio.dxfer_len, in mvs_legacy_execute_transaction()
1331 ch->curr[port].bytecount); in mvs_legacy_execute_transaction()
1333 ch->transfersize = min(ccb->ataio.dxfer_len, 512); in mvs_legacy_execute_transaction()
1334 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) in mvs_legacy_execute_transaction()
1335 ch->fake_busy = 1; in mvs_legacy_execute_transaction()
1336 /* If data write command - output the data */ in mvs_legacy_execute_transaction()
1337 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { in mvs_legacy_execute_transaction()
1340 "timeout waiting for write DRQ\n"); in mvs_legacy_execute_transaction()
1341 xpt_freeze_simq(ch->sim, 1); in mvs_legacy_execute_transaction()
1342 ch->toslots |= (1 << slot->slot); in mvs_legacy_execute_transaction()
1346 ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_execute_transaction()
1347 (uint16_t *)(ccb->ataio.data_ptr + ch->donecount), in mvs_legacy_execute_transaction()
1348 ch->transfersize / 2); in mvs_legacy_execute_transaction()
1351 ch->donecount = 0; in mvs_legacy_execute_transaction()
1352 ch->transfersize = min(ccb->csio.dxfer_len, in mvs_legacy_execute_transaction()
1353 ch->curr[port].bytecount); in mvs_legacy_execute_transaction()
1355 if (ch->basic_dma) { in mvs_legacy_execute_transaction()
1356 ATA_OUTB(ch->r_mem, ATA_FEATURE, ATA_F_DMA); in mvs_legacy_execute_transaction()
1357 ATA_OUTB(ch->r_mem, ATA_CYL_LSB, 0); in mvs_legacy_execute_transaction()
1358 ATA_OUTB(ch->r_mem, ATA_CYL_MSB, 0); in mvs_legacy_execute_transaction()
1360 ATA_OUTB(ch->r_mem, ATA_FEATURE, 0); in mvs_legacy_execute_transaction()
1361 ATA_OUTB(ch->r_mem, ATA_CYL_LSB, ch->transfersize); in mvs_legacy_execute_transaction()
1362 ATA_OUTB(ch->r_mem, ATA_CYL_MSB, ch->transfersize >> 8); in mvs_legacy_execute_transaction()
1364 ATA_OUTB(ch->r_mem, ATA_COMMAND, ATA_PACKET_CMD); in mvs_legacy_execute_transaction()
1365 ch->fake_busy = 1; in mvs_legacy_execute_transaction()
1368 device_printf(dev, "timeout waiting for ATAPI !BUSY\n"); in mvs_legacy_execute_transaction()
1369 xpt_freeze_simq(ch->sim, 1); in mvs_legacy_execute_transaction()
1370 ch->toslots |= (1 << slot->slot); in mvs_legacy_execute_transaction()
1374 timeout = 5000; in mvs_legacy_execute_transaction()
1375 while (timeout--) { in mvs_legacy_execute_transaction()
1376 int reason = ATA_INB(ch->r_mem, ATA_IREASON); in mvs_legacy_execute_transaction()
1377 int status = ATA_INB(ch->r_mem, ATA_STATUS); in mvs_legacy_execute_transaction()
1384 if (timeout <= 0) { in mvs_legacy_execute_transaction()
1386 "timeout waiting for ATAPI command ready\n"); in mvs_legacy_execute_transaction()
1387 xpt_freeze_simq(ch->sim, 1); in mvs_legacy_execute_transaction()
1388 ch->toslots |= (1 << slot->slot); in mvs_legacy_execute_transaction()
1393 ATA_OUTSW_STRM(ch->r_mem, ATA_DATA, in mvs_legacy_execute_transaction()
1394 (uint16_t *)((ccb->ccb_h.flags & CAM_CDB_POINTER) ? in mvs_legacy_execute_transaction()
1395 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes), in mvs_legacy_execute_transaction()
1396 ch->curr[port].atapi / 2); in mvs_legacy_execute_transaction()
1398 if (ch->basic_dma) { in mvs_legacy_execute_transaction()
1400 eprd = ch->dma.workrq_bus + slot->eprd_offset; in mvs_legacy_execute_transaction()
1401 ATA_OUTL(ch->r_mem, DMA_DTLBA, eprd); in mvs_legacy_execute_transaction()
1402 ATA_OUTL(ch->r_mem, DMA_DTHBA, (eprd >> 16) >> 16); in mvs_legacy_execute_transaction()
1403 ATA_OUTL(ch->r_mem, DMA_C, DMA_C_START | in mvs_legacy_execute_transaction()
1404 (((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) ? in mvs_legacy_execute_transaction()
1408 /* Start command execution timeout */ in mvs_legacy_execute_transaction()
1409 callout_reset_sbt(&slot->timeout, SBT_1MS * ccb->ccb_h.timeout, 0, in mvs_legacy_execute_transaction()
1417 device_t dev = slot->dev; in mvs_execute_transaction()
1422 union ccb *ccb = slot->ccb; in mvs_execute_transaction()
1423 int port = ccb->ccb_h.target_id & 0x0f; in mvs_execute_transaction()
1427 eprd = ch->dma.workrq_bus + slot->eprd_offset; in mvs_execute_transaction()
1429 if (ch->quirks & MVS_Q_GENIIE) { in mvs_execute_transaction()
1431 (ch->dma.workrq + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx)); in mvs_execute_transaction()
1432 crqb2e->ctrlflg = htole32( in mvs_execute_transaction()
1433 ((ccb->ccb_h.flags & CAM_DIR_IN) ? MVS_CRQB2E_READ : 0) | in mvs_execute_transaction()
1434 (slot->tag << MVS_CRQB2E_DTAG_SHIFT) | in mvs_execute_transaction()
1436 (slot->slot << MVS_CRQB2E_HTAG_SHIFT)); in mvs_execute_transaction()
1437 /* If there is only one segment - no need to use S/G table. */ in mvs_execute_transaction()
1438 if (slot->dma.addr != 0) { in mvs_execute_transaction()
1439 eprd = slot->dma.addr; in mvs_execute_transaction()
1440 crqb2e->ctrlflg |= htole32(MVS_CRQB2E_CPRD); in mvs_execute_transaction()
1441 crqb2e->drbc = slot->dma.len; in mvs_execute_transaction()
1443 crqb2e->cprdbl = htole32(eprd); in mvs_execute_transaction()
1444 crqb2e->cprdbh = htole32((eprd >> 16) >> 16); in mvs_execute_transaction()
1445 crqb2e->cmd[0] = 0; in mvs_execute_transaction()
1446 crqb2e->cmd[1] = 0; in mvs_execute_transaction()
1447 crqb2e->cmd[2] = ccb->ataio.cmd.command; in mvs_execute_transaction()
1448 crqb2e->cmd[3] = ccb->ataio.cmd.features; in mvs_execute_transaction()
1449 crqb2e->cmd[4] = ccb->ataio.cmd.lba_low; in mvs_execute_transaction()
1450 crqb2e->cmd[5] = ccb->ataio.cmd.lba_mid; in mvs_execute_transaction()
1451 crqb2e->cmd[6] = ccb->ataio.cmd.lba_high; in mvs_execute_transaction()
1452 crqb2e->cmd[7] = ccb->ataio.cmd.device; in mvs_execute_transaction()
1453 crqb2e->cmd[8] = ccb->ataio.cmd.lba_low_exp; in mvs_execute_transaction()
1454 crqb2e->cmd[9] = ccb->ataio.cmd.lba_mid_exp; in mvs_execute_transaction()
1455 crqb2e->cmd[10] = ccb->ataio.cmd.lba_high_exp; in mvs_execute_transaction()
1456 crqb2e->cmd[11] = ccb->ataio.cmd.features_exp; in mvs_execute_transaction()
1457 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_execute_transaction()
1458 crqb2e->cmd[12] = slot->tag << 3; in mvs_execute_transaction()
1459 crqb2e->cmd[13] = 0; in mvs_execute_transaction()
1461 crqb2e->cmd[12] = ccb->ataio.cmd.sector_count; in mvs_execute_transaction()
1462 crqb2e->cmd[13] = ccb->ataio.cmd.sector_count_exp; in mvs_execute_transaction()
1464 crqb2e->cmd[14] = 0; in mvs_execute_transaction()
1465 crqb2e->cmd[15] = 0; in mvs_execute_transaction()
1468 (ch->dma.workrq + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx)); in mvs_execute_transaction()
1469 crqb->cprdbl = htole32(eprd); in mvs_execute_transaction()
1470 crqb->cprdbh = htole32((eprd >> 16) >> 16); in mvs_execute_transaction()
1471 crqb->ctrlflg = htole16( in mvs_execute_transaction()
1472 ((ccb->ccb_h.flags & CAM_DIR_IN) ? MVS_CRQB_READ : 0) | in mvs_execute_transaction()
1473 (slot->slot << MVS_CRQB_TAG_SHIFT) | in mvs_execute_transaction()
1480 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_execute_transaction()
1481 crqb->cmd[i++] = ccb->ataio.cmd.features_exp; in mvs_execute_transaction()
1482 crqb->cmd[i++] = 0x11; in mvs_execute_transaction()
1484 crqb->cmd[i++] = ccb->ataio.cmd.features; in mvs_execute_transaction()
1485 crqb->cmd[i++] = 0x11; in mvs_execute_transaction()
1486 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_execute_transaction()
1487 crqb->cmd[i++] = (slot->tag << 3) | in mvs_execute_transaction()
1488 (ccb->ataio.cmd.sector_count & 0x07); in mvs_execute_transaction()
1489 crqb->cmd[i++] = 0x12; in mvs_execute_transaction()
1491 crqb->cmd[i++] = ccb->ataio.cmd.sector_count_exp; in mvs_execute_transaction()
1492 crqb->cmd[i++] = 0x12; in mvs_execute_transaction()
1493 crqb->cmd[i++] = ccb->ataio.cmd.sector_count; in mvs_execute_transaction()
1494 crqb->cmd[i++] = 0x12; in mvs_execute_transaction()
1496 crqb->cmd[i++] = ccb->ataio.cmd.lba_low_exp; in mvs_execute_transaction()
1497 crqb->cmd[i++] = 0x13; in mvs_execute_transaction()
1498 crqb->cmd[i++] = ccb->ataio.cmd.lba_low; in mvs_execute_transaction()
1499 crqb->cmd[i++] = 0x13; in mvs_execute_transaction()
1500 crqb->cmd[i++] = ccb->ataio.cmd.lba_mid_exp; in mvs_execute_transaction()
1501 crqb->cmd[i++] = 0x14; in mvs_execute_transaction()
1502 crqb->cmd[i++] = ccb->ataio.cmd.lba_mid; in mvs_execute_transaction()
1503 crqb->cmd[i++] = 0x14; in mvs_execute_transaction()
1504 crqb->cmd[i++] = ccb->ataio.cmd.lba_high_exp; in mvs_execute_transaction()
1505 crqb->cmd[i++] = 0x15; in mvs_execute_transaction()
1506 crqb->cmd[i++] = ccb->ataio.cmd.lba_high; in mvs_execute_transaction()
1507 crqb->cmd[i++] = 0x15; in mvs_execute_transaction()
1508 crqb->cmd[i++] = ccb->ataio.cmd.device; in mvs_execute_transaction()
1509 crqb->cmd[i++] = 0x16; in mvs_execute_transaction()
1510 crqb->cmd[i++] = ccb->ataio.cmd.command; in mvs_execute_transaction()
1511 crqb->cmd[i++] = 0x97; in mvs_execute_transaction()
1513 bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map, in mvs_execute_transaction()
1515 bus_dmamap_sync(ch->dma.workrp_tag, ch->dma.workrp_map, in mvs_execute_transaction()
1517 slot->state = MVS_SLOT_RUNNING; in mvs_execute_transaction()
1518 ch->rslots |= (1 << slot->slot); in mvs_execute_transaction()
1520 ch->out_idx = (ch->out_idx + 1) & (MVS_MAX_SLOTS - 1); in mvs_execute_transaction()
1521 ATA_OUTL(ch->r_mem, EDMA_REQQIP, in mvs_execute_transaction()
1522 ch->dma.workrq_bus + MVS_CRQB_OFFSET + (MVS_CRQB_SIZE * ch->out_idx)); in mvs_execute_transaction()
1523 /* Start command execution timeout */ in mvs_execute_transaction()
1524 callout_reset_sbt(&slot->timeout, SBT_1MS * ccb->ccb_h.timeout, 0, in mvs_execute_transaction()
1536 mtx_assert(&ch->mtx, MA_OWNED); in mvs_process_timeout()
1540 if (ch->slot[i].state < MVS_SLOT_RUNNING) in mvs_process_timeout()
1542 mvs_end_transaction(&ch->slot[i], MVS_ERR_TIMEOUT); in mvs_process_timeout()
1553 mtx_assert(&ch->mtx, MA_OWNED); in mvs_rearm_timeout()
1555 struct mvs_slot *slot = &ch->slot[i]; in mvs_rearm_timeout()
1558 if (slot->state < MVS_SLOT_RUNNING) in mvs_rearm_timeout()
1560 if ((ch->toslots & (1 << i)) == 0) in mvs_rearm_timeout()
1562 callout_reset_sbt(&slot->timeout, in mvs_rearm_timeout()
1563 SBT_1MS * slot->ccb->ccb_h.timeout / 2, 0, in mvs_rearm_timeout()
1573 device_t dev = slot->dev; in mvs_timeout()
1576 /* Check for stale timeout. */ in mvs_timeout()
1577 if (slot->state < MVS_SLOT_RUNNING) in mvs_timeout()
1579 device_printf(dev, "Timeout on slot %d\n", slot->slot); in mvs_timeout()
1582 ATA_INL(ch->r_mem, EDMA_IEC), in mvs_timeout()
1583 ATA_INL(ch->r_mem, SATA_SS), ATA_INL(ch->r_mem, SATA_SE), in mvs_timeout()
1584 ATA_INL(ch->r_mem, EDMA_S), ATA_INL(ch->r_mem, DMA_C), in mvs_timeout()
1585 ATA_INL(ch->r_mem, DMA_S), ch->rslots, in mvs_timeout()
1586 ATA_INB(ch->r_mem, ATA_ALTSTAT)); in mvs_timeout()
1589 /* We wait for other commands timeout and pray. */ in mvs_timeout()
1590 if (ch->toslots == 0) in mvs_timeout()
1591 xpt_freeze_simq(ch->sim, 1); in mvs_timeout()
1592 ch->toslots |= (1 << slot->slot); in mvs_timeout()
1593 if ((ch->rslots & ~ch->toslots) == 0) in mvs_timeout()
1597 ch->rslots & ~ch->toslots); in mvs_timeout()
1604 device_t dev = slot->dev; in mvs_end_transaction()
1606 union ccb *ccb = slot->ccb; in mvs_end_transaction()
1609 bus_dmamap_sync(ch->dma.workrq_tag, ch->dma.workrq_map, in mvs_end_transaction()
1615 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in mvs_end_transaction()
1616 struct ata_res *res = &ccb->ataio.res; in mvs_end_transaction()
1619 (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { in mvs_end_transaction()
1624 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && in mvs_end_transaction()
1625 ch->basic_dma == 0) in mvs_end_transaction()
1626 ccb->csio.resid = ccb->csio.dxfer_len - ch->donecount; in mvs_end_transaction()
1628 if (ch->numpslots == 0 || ch->basic_dma) { in mvs_end_transaction()
1629 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in mvs_end_transaction()
1630 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, in mvs_end_transaction()
1631 (ccb->ccb_h.flags & CAM_DIR_IN) ? in mvs_end_transaction()
1633 bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map); in mvs_end_transaction()
1637 ch->eslots |= (1 << slot->slot); in mvs_end_transaction()
1639 if ((et != MVS_ERR_NONE) && (!ch->recoverycmd) && in mvs_end_transaction()
1640 !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { in mvs_end_transaction()
1641 xpt_freeze_devq(ccb->ccb_h.path, 1); in mvs_end_transaction()
1642 ccb->ccb_h.status |= CAM_DEV_QFRZN; in mvs_end_transaction()
1645 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_end_transaction()
1648 ccb->ccb_h.status |= CAM_REQ_CMP; in mvs_end_transaction()
1649 if (ccb->ccb_h.func_code == XPT_SCSI_IO) in mvs_end_transaction()
1650 ccb->csio.scsi_status = SCSI_STATUS_OK; in mvs_end_transaction()
1653 ch->fatalerr = 1; in mvs_end_transaction()
1654 ccb->ccb_h.status |= CAM_REQ_INVALID; in mvs_end_transaction()
1657 ccb->ccb_h.status |= CAM_REQUEUE_REQ; in mvs_end_transaction()
1661 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in mvs_end_transaction()
1662 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; in mvs_end_transaction()
1663 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; in mvs_end_transaction()
1665 ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; in mvs_end_transaction()
1669 ch->fatalerr = 1; in mvs_end_transaction()
1670 if (!ch->recoverycmd) { in mvs_end_transaction()
1671 xpt_freeze_simq(ch->sim, 1); in mvs_end_transaction()
1672 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_end_transaction()
1673 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; in mvs_end_transaction()
1675 ccb->ccb_h.status |= CAM_UNCOR_PARITY; in mvs_end_transaction()
1678 if (!ch->recoverycmd) { in mvs_end_transaction()
1679 xpt_freeze_simq(ch->sim, 1); in mvs_end_transaction()
1680 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_end_transaction()
1681 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; in mvs_end_transaction()
1683 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; in mvs_end_transaction()
1686 ch->fatalerr = 1; in mvs_end_transaction()
1687 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; in mvs_end_transaction()
1690 ch->oslots &= ~(1 << slot->slot); in mvs_end_transaction()
1691 ch->rslots &= ~(1 << slot->slot); in mvs_end_transaction()
1692 ch->aslots &= ~(1 << slot->slot); in mvs_end_transaction()
1693 slot->state = MVS_SLOT_EMPTY; in mvs_end_transaction()
1694 slot->ccb = NULL; in mvs_end_transaction()
1696 ch->numrslots--; in mvs_end_transaction()
1697 ch->numrslotspd[ccb->ccb_h.target_id]--; in mvs_end_transaction()
1698 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in mvs_end_transaction()
1699 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in mvs_end_transaction()
1700 ch->otagspd[ccb->ccb_h.target_id] &= ~(1 << slot->tag); in mvs_end_transaction()
1701 ch->numtslots--; in mvs_end_transaction()
1702 ch->numtslotspd[ccb->ccb_h.target_id]--; in mvs_end_transaction()
1703 } else if (ccb->ataio.cmd.flags & CAM_ATAIO_DMA) { in mvs_end_transaction()
1704 ch->numdslots--; in mvs_end_transaction()
1706 ch->numpslots--; in mvs_end_transaction()
1709 ch->numpslots--; in mvs_end_transaction()
1710 ch->basic_dma = 0; in mvs_end_transaction()
1712 /* Cancel timeout state if request completed normally. */ in mvs_end_transaction()
1714 lastto = (ch->toslots == (1 << slot->slot)); in mvs_end_transaction()
1715 ch->toslots &= ~(1 << slot->slot); in mvs_end_transaction()
1717 xpt_release_simq(ch->sim, TRUE); in mvs_end_transaction()
1719 /* If it was our READ LOG command - process it. */ in mvs_end_transaction()
1720 if (ccb->ccb_h.recovery_type == RECOVERY_READ_LOG) { in mvs_end_transaction()
1722 /* If it was our REQUEST SENSE command - process it. */ in mvs_end_transaction()
1723 } else if (ccb->ccb_h.recovery_type == RECOVERY_REQUEST_SENSE) { in mvs_end_transaction()
1727 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && in mvs_end_transaction()
1728 (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)) { in mvs_end_transaction()
1729 ch->hold[slot->slot] = ccb; in mvs_end_transaction()
1730 ch->holdtag[slot->slot] = slot->tag; in mvs_end_transaction()
1731 ch->numhslots++; in mvs_end_transaction()
1735 if (ch->rslots == 0) { in mvs_end_transaction()
1736 /* if there was fatal error - reset port. */ in mvs_end_transaction()
1737 if (ch->toslots != 0 || ch->fatalerr) { in mvs_end_transaction()
1741 if (ch->eslots != 0) { in mvs_end_transaction()
1743 ch->eslots = 0; in mvs_end_transaction()
1746 if (!ch->recoverycmd && ch->numhslots) in mvs_end_transaction()
1749 /* If all the rest of commands are in timeout - give them chance. */ in mvs_end_transaction()
1750 } else if ((ch->rslots & ~ch->toslots) == 0 && in mvs_end_transaction()
1754 if (ch->frozen && !mvs_check_collision(dev, ch->frozen)) { in mvs_end_transaction()
1755 union ccb *fccb = ch->frozen; in mvs_end_transaction()
1756 ch->frozen = NULL; in mvs_end_transaction()
1758 xpt_release_simq(ch->sim, TRUE); in mvs_end_transaction()
1761 if (ch->numrslots == 0 && ch->pm_level > 3 && in mvs_end_transaction()
1762 (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { in mvs_end_transaction()
1763 callout_schedule(&ch->pm_timer, in mvs_end_transaction()
1764 (ch->pm_level == 4) ? hz / 1000 : hz / 8); in mvs_end_transaction()
1779 if (ch->hold[i]) in mvs_issue_recovery()
1786 /* We can't do anything -- complete held commands. */ in mvs_issue_recovery()
1788 if (ch->hold[i] == NULL) in mvs_issue_recovery()
1790 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_issue_recovery()
1791 ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL; in mvs_issue_recovery()
1792 xpt_done(ch->hold[i]); in mvs_issue_recovery()
1793 ch->hold[i] = NULL; in mvs_issue_recovery()
1794 ch->numhslots--; in mvs_issue_recovery()
1799 xpt_setup_ccb(&ccb->ccb_h, ch->hold[i]->ccb_h.path, in mvs_issue_recovery()
1800 ch->hold[i]->ccb_h.pinfo.priority); in mvs_issue_recovery()
1801 if (ch->hold[i]->ccb_h.func_code == XPT_ATA_IO) { in mvs_issue_recovery()
1803 ccb->ccb_h.recovery_type = RECOVERY_READ_LOG; in mvs_issue_recovery()
1804 ccb->ccb_h.func_code = XPT_ATA_IO; in mvs_issue_recovery()
1805 ccb->ccb_h.flags = CAM_DIR_IN; in mvs_issue_recovery()
1806 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ in mvs_issue_recovery()
1807 ataio = &ccb->ataio; in mvs_issue_recovery()
1808 ataio->data_ptr = malloc(512, M_MVS, M_NOWAIT); in mvs_issue_recovery()
1809 if (ataio->data_ptr == NULL) { in mvs_issue_recovery()
1815 ataio->dxfer_len = 512; in mvs_issue_recovery()
1816 bzero(&ataio->cmd, sizeof(ataio->cmd)); in mvs_issue_recovery()
1817 ataio->cmd.flags = CAM_ATAIO_48BIT; in mvs_issue_recovery()
1818 ataio->cmd.command = 0x2F; /* READ LOG EXT */ in mvs_issue_recovery()
1819 ataio->cmd.sector_count = 1; in mvs_issue_recovery()
1820 ataio->cmd.sector_count_exp = 0; in mvs_issue_recovery()
1821 ataio->cmd.lba_low = 0x10; in mvs_issue_recovery()
1822 ataio->cmd.lba_mid = 0; in mvs_issue_recovery()
1823 ataio->cmd.lba_mid_exp = 0; in mvs_issue_recovery()
1826 ccb->ccb_h.recovery_type = RECOVERY_REQUEST_SENSE; in mvs_issue_recovery()
1827 ccb->ccb_h.recovery_slot = i; in mvs_issue_recovery()
1828 ccb->ccb_h.func_code = XPT_SCSI_IO; in mvs_issue_recovery()
1829 ccb->ccb_h.flags = CAM_DIR_IN; in mvs_issue_recovery()
1830 ccb->ccb_h.status = 0; in mvs_issue_recovery()
1831 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ in mvs_issue_recovery()
1832 csio = &ccb->csio; in mvs_issue_recovery()
1833 csio->data_ptr = (void *)&ch->hold[i]->csio.sense_data; in mvs_issue_recovery()
1834 csio->dxfer_len = ch->hold[i]->csio.sense_len; in mvs_issue_recovery()
1835 csio->cdb_len = 6; in mvs_issue_recovery()
1836 bzero(&csio->cdb_io, sizeof(csio->cdb_io)); in mvs_issue_recovery()
1837 csio->cdb_io.cdb_bytes[0] = 0x03; in mvs_issue_recovery()
1838 csio->cdb_io.cdb_bytes[4] = csio->dxfer_len; in mvs_issue_recovery()
1841 ch->recoverycmd = 1; in mvs_issue_recovery()
1842 xpt_freeze_simq(ch->sim, 1); in mvs_issue_recovery()
1854 ch->recoverycmd = 0; in mvs_process_read_log()
1856 data = ccb->ataio.data_ptr; in mvs_process_read_log()
1857 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && in mvs_process_read_log()
1860 if (!ch->hold[i]) in mvs_process_read_log()
1862 if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id) in mvs_process_read_log()
1864 if ((data[0] & 0x1F) == ch->holdtag[i]) { in mvs_process_read_log()
1865 res = &ch->hold[i]->ataio.res; in mvs_process_read_log()
1866 res->status = data[2]; in mvs_process_read_log()
1867 res->error = data[3]; in mvs_process_read_log()
1868 res->lba_low = data[4]; in mvs_process_read_log()
1869 res->lba_mid = data[5]; in mvs_process_read_log()
1870 res->lba_high = data[6]; in mvs_process_read_log()
1871 res->device = data[7]; in mvs_process_read_log()
1872 res->lba_low_exp = data[8]; in mvs_process_read_log()
1873 res->lba_mid_exp = data[9]; in mvs_process_read_log()
1874 res->lba_high_exp = data[10]; in mvs_process_read_log()
1875 res->sector_count = data[12]; in mvs_process_read_log()
1876 res->sector_count_exp = data[13]; in mvs_process_read_log()
1878 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_process_read_log()
1879 ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ; in mvs_process_read_log()
1881 xpt_done(ch->hold[i]); in mvs_process_read_log()
1882 ch->hold[i] = NULL; in mvs_process_read_log()
1883 ch->numhslots--; in mvs_process_read_log()
1886 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) in mvs_process_read_log()
1890 "Non-queued command error in READ LOG EXT\n"); in mvs_process_read_log()
1893 if (!ch->hold[i]) in mvs_process_read_log()
1895 if (ch->hold[i]->ccb_h.target_id != ccb->ccb_h.target_id) in mvs_process_read_log()
1897 xpt_done(ch->hold[i]); in mvs_process_read_log()
1898 ch->hold[i] = NULL; in mvs_process_read_log()
1899 ch->numhslots--; in mvs_process_read_log()
1902 free(ccb->ataio.data_ptr, M_MVS); in mvs_process_read_log()
1904 xpt_release_simq(ch->sim, TRUE); in mvs_process_read_log()
1913 ch->recoverycmd = 0; in mvs_process_request_sense()
1915 i = ccb->ccb_h.recovery_slot; in mvs_process_request_sense()
1916 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { in mvs_process_request_sense()
1917 ch->hold[i]->ccb_h.status |= CAM_AUTOSNS_VALID; in mvs_process_request_sense()
1919 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_process_request_sense()
1920 ch->hold[i]->ccb_h.status |= CAM_AUTOSENSE_FAIL; in mvs_process_request_sense()
1922 xpt_done(ch->hold[i]); in mvs_process_request_sense()
1923 ch->hold[i] = NULL; in mvs_process_request_sense()
1924 ch->numhslots--; in mvs_process_request_sense()
1926 xpt_release_simq(ch->sim, TRUE); in mvs_process_request_sense()
1932 int timeout = 0; in mvs_wait() local
1936 if (timeout >= t) { in mvs_wait()
1939 return (-1); in mvs_wait()
1942 timeout++; in mvs_wait()
1944 return (timeout); in mvs_wait()
1951 union ccb *fccb = ch->frozen; in mvs_requeue_frozen()
1954 ch->frozen = NULL; in mvs_requeue_frozen()
1955 fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; in mvs_requeue_frozen()
1956 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { in mvs_requeue_frozen()
1957 xpt_freeze_devq(fccb->ccb_h.path, 1); in mvs_requeue_frozen()
1958 fccb->ccb_h.status |= CAM_DEV_QFRZN; in mvs_requeue_frozen()
1971 if (ch->resetting == 0) in mvs_reset_to()
1973 ch->resetting--; in mvs_reset_to()
1978 (310 - ch->resetting) * 100); in mvs_reset_to()
1980 ch->resetting = 0; in mvs_reset_to()
1981 xpt_release_simq(ch->sim, TRUE); in mvs_reset_to()
1984 if (ch->resetting == 0) { in mvs_reset_to()
1986 "MVS reset: device not ready after 31000ms\n"); in mvs_reset_to()
1987 xpt_release_simq(ch->sim, TRUE); in mvs_reset_to()
1990 callout_schedule(&ch->reset_timer, hz / 10); in mvs_reset_to()
1999 if (ch->quirks & MVS_Q_SOC65) { in mvs_errata()
2000 val = ATA_INL(ch->r_mem, SATA_PHYM3); in mvs_errata()
2005 ATA_OUTL(ch->r_mem, SATA_PHYM3, val); in mvs_errata()
2007 val = ATA_INL(ch->r_mem, SATA_PHYM4); in mvs_errata()
2010 ATA_OUTL(ch->r_mem, SATA_PHYM4, val); in mvs_errata()
2012 val = ATA_INL(ch->r_mem, SATA_PHYM9_GEN2); in mvs_errata()
2016 ATA_OUTL(ch->r_mem, SATA_PHYM9_GEN2, val); in mvs_errata()
2018 val = ATA_INL(ch->r_mem, SATA_PHYM9_GEN1); in mvs_errata()
2022 ATA_OUTL(ch->r_mem, SATA_PHYM9_GEN1, val); in mvs_errata()
2032 xpt_freeze_simq(ch->sim, 1); in mvs_reset()
2036 if (ch->resetting) { in mvs_reset()
2037 ch->resetting = 0; in mvs_reset()
2038 callout_stop(&ch->reset_timer); in mvs_reset()
2039 xpt_release_simq(ch->sim, TRUE); in mvs_reset()
2045 ATA_OUTL(ch->r_mem, DMA_C, 0); in mvs_reset()
2048 if (ch->slot[i].state < MVS_SLOT_RUNNING) in mvs_reset()
2051 mvs_end_transaction(&ch->slot[i], MVS_ERR_INNOCENT); in mvs_reset()
2054 if (!ch->hold[i]) in mvs_reset()
2056 xpt_done(ch->hold[i]); in mvs_reset()
2057 ch->hold[i] = NULL; in mvs_reset()
2058 ch->numhslots--; in mvs_reset()
2060 if (ch->toslots != 0) in mvs_reset()
2061 xpt_release_simq(ch->sim, TRUE); in mvs_reset()
2062 ch->eslots = 0; in mvs_reset()
2063 ch->toslots = 0; in mvs_reset()
2064 ch->fatalerr = 0; in mvs_reset()
2065 ch->fake_busy = 0; in mvs_reset()
2067 xpt_async(AC_BUS_RESET, ch->path, NULL); in mvs_reset()
2068 ATA_OUTL(ch->r_mem, EDMA_IEM, 0); in mvs_reset()
2069 ATA_OUTL(ch->r_mem, EDMA_CMD, EDMA_CMD_EATARST); in mvs_reset()
2071 ATA_OUTL(ch->r_mem, EDMA_CMD, 0); in mvs_reset()
2077 ch->devices = 0; in mvs_reset()
2078 ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff); in mvs_reset()
2079 ATA_OUTL(ch->r_mem, EDMA_IEC, 0); in mvs_reset()
2080 ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT); in mvs_reset()
2081 xpt_release_simq(ch->sim, TRUE); in mvs_reset()
2091 "MVS reset: device not ready after 31000ms\n"); in mvs_reset()
2093 ch->resetting = 310; in mvs_reset()
2096 ch->devices = 1; in mvs_reset()
2097 ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff); in mvs_reset()
2098 ATA_OUTL(ch->r_mem, EDMA_IEC, 0); in mvs_reset()
2099 ATA_OUTL(ch->r_mem, EDMA_IEM, ~EDMA_IE_TRANSIENT); in mvs_reset()
2100 if (ch->resetting) in mvs_reset()
2101 callout_reset(&ch->reset_timer, hz / 10, mvs_reset_to, dev); in mvs_reset()
2103 xpt_release_simq(ch->sim, TRUE); in mvs_reset()
2110 int port = ccb->ccb_h.target_id & 0x0f; in mvs_softreset()
2115 ATA_OUTB(ch->r_mem, SATA_SATAICTL, port << SATA_SATAICTL_PMPTX_SHIFT); in mvs_softreset()
2116 ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET); in mvs_softreset()
2118 ATA_OUTB(ch->r_mem, ATA_CONTROL, 0); in mvs_softreset()
2119 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in mvs_softreset()
2121 if ((i = mvs_wait(dev, 0, ATA_S_BUSY, ccb->ccb_h.timeout)) < 0) { in mvs_softreset()
2122 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; in mvs_softreset()
2127 ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; in mvs_softreset()
2129 ccb->ccb_h.status |= CAM_REQ_CMP; in mvs_softreset()
2138 * XXX: If some device on PMP failed to soft-reset, in mvs_softreset()
2139 * try to recover by sending dummy soft-reset to PMP. in mvs_softreset()
2141 if (stuck && ch->pm_present && port != 15) { in mvs_softreset()
2142 ATA_OUTB(ch->r_mem, SATA_SATAICTL, in mvs_softreset()
2144 ATA_OUTB(ch->r_mem, ATA_CONTROL, ATA_A_RESET); in mvs_softreset()
2146 ATA_OUTB(ch->r_mem, ATA_CONTROL, 0); in mvs_softreset()
2147 mvs_wait(dev, 0, ATA_S_BUSY | ATA_S_DRQ, ccb->ccb_h.timeout); in mvs_softreset()
2157 int timeout, found = 0; in mvs_sata_connect() local
2159 /* Wait up to 100ms for "connect well" */ in mvs_sata_connect()
2160 for (timeout = 0; timeout < 1000 ; timeout++) { in mvs_sata_connect()
2161 status = ATA_INL(ch->r_mem, SATA_SS); in mvs_sata_connect()
2170 device_printf(ch->dev, "SATA offline status=%08x\n", in mvs_sata_connect()
2175 if (found == 0 && timeout >= 100) in mvs_sata_connect()
2179 if (timeout >= 1000 || !found) { in mvs_sata_connect()
2181 device_printf(ch->dev, in mvs_sata_connect()
2182 "SATA connect timeout time=%dus status=%08x\n", in mvs_sata_connect()
2183 timeout * 100, status); in mvs_sata_connect()
2188 device_printf(ch->dev, "SATA connect time=%dus status=%08x\n", in mvs_sata_connect()
2189 timeout * 100, status); in mvs_sata_connect()
2192 ATA_OUTL(ch->r_mem, SATA_SE, 0xffffffff); in mvs_sata_connect()
2203 sata_rev = ch->user[ch->pm_present ? 15 : 0].revision; in mvs_sata_phy_reset()
2212 ATA_OUTL(ch->r_mem, SATA_SC, in mvs_sata_phy_reset()
2216 ATA_OUTL(ch->r_mem, SATA_SC, in mvs_sata_phy_reset()
2217 SATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 : in mvs_sata_phy_reset()
2220 if (ch->pm_level > 0) in mvs_sata_phy_reset()
2221 ATA_OUTL(ch->r_mem, SATA_SC, SATA_SC_DET_DISABLE); in mvs_sata_phy_reset()
2232 if (ccb->ccb_h.target_id > ((ch->quirks & MVS_Q_GENI) ? 0 : 15)) { in mvs_check_ids()
2233 ccb->ccb_h.status = CAM_TID_INVALID; in mvs_check_ids()
2235 return (-1); in mvs_check_ids()
2237 if (ccb->ccb_h.target_lun != 0) { in mvs_check_ids()
2238 ccb->ccb_h.status = CAM_LUN_INVALID; in mvs_check_ids()
2240 return (-1); in mvs_check_ids()
2245 KASSERT(ccb->ccb_h.func_code != XPT_ATA_IO || in mvs_check_ids()
2246 ((ccb->ataio.ata_flags & ATA_FLAG_AUX) == 0), in mvs_check_ids()
2257 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mvsaction func_code=%x\n", in mvsaction()
2258 ccb->ccb_h.func_code)); in mvsaction()
2261 dev = ch->dev; in mvsaction()
2262 switch (ccb->ccb_h.func_code) { in mvsaction()
2268 if (ch->devices == 0 || in mvsaction()
2269 (ch->pm_present == 0 && in mvsaction()
2270 ccb->ccb_h.target_id > 0 && ccb->ccb_h.target_id < 15)) { in mvsaction()
2271 ccb->ccb_h.status = CAM_SEL_TIMEOUT; in mvsaction()
2274 ccb->ccb_h.recovery_type = RECOVERY_NONE; in mvsaction()
2278 ch->frozen = ccb; in mvsaction()
2280 xpt_freeze_simq(ch->sim, 1); in mvsaction()
2287 ccb->ccb_h.status = CAM_REQ_INVALID; in mvsaction()
2291 struct ccb_trans_settings *cts = &ccb->cts; in mvsaction()
2296 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) in mvsaction()
2297 d = &ch->curr[ccb->ccb_h.target_id]; in mvsaction()
2299 d = &ch->user[ccb->ccb_h.target_id]; in mvsaction()
2300 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) in mvsaction()
2301 d->revision = cts->xport_specific.sata.revision; in mvsaction()
2302 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) in mvsaction()
2303 d->mode = cts->xport_specific.sata.mode; in mvsaction()
2304 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) { in mvsaction()
2305 d->bytecount = min((ch->quirks & MVS_Q_GENIIE) ? 8192 : 2048, in mvsaction()
2306 cts->xport_specific.sata.bytecount); in mvsaction()
2308 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) in mvsaction()
2309 d->tags = min(MVS_MAX_SLOTS, cts->xport_specific.sata.tags); in mvsaction()
2310 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) in mvsaction()
2311 ch->pm_present = cts->xport_specific.sata.pm_present; in mvsaction()
2312 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI) in mvsaction()
2313 d->atapi = cts->xport_specific.sata.atapi; in mvsaction()
2314 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS) in mvsaction()
2315 d->caps = cts->xport_specific.sata.caps; in mvsaction()
2316 ccb->ccb_h.status = CAM_REQ_CMP; in mvsaction()
2322 struct ccb_trans_settings *cts = &ccb->cts; in mvsaction()
2328 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) in mvsaction()
2329 d = &ch->curr[ccb->ccb_h.target_id]; in mvsaction()
2331 d = &ch->user[ccb->ccb_h.target_id]; in mvsaction()
2332 cts->protocol = PROTO_UNSPECIFIED; in mvsaction()
2333 cts->protocol_version = PROTO_VERSION_UNSPECIFIED; in mvsaction()
2334 cts->transport = XPORT_SATA; in mvsaction()
2335 cts->transport_version = XPORT_VERSION_UNSPECIFIED; in mvsaction()
2336 cts->proto_specific.valid = 0; in mvsaction()
2337 cts->xport_specific.sata.valid = 0; in mvsaction()
2338 if (cts->type == CTS_TYPE_CURRENT_SETTINGS && in mvsaction()
2339 (ccb->ccb_h.target_id == 15 || in mvsaction()
2340 (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { in mvsaction()
2341 status = ATA_INL(ch->r_mem, SATA_SS) & SATA_SS_SPD_MASK; in mvsaction()
2343 cts->xport_specific.sata.revision = in mvsaction()
2345 cts->xport_specific.sata.valid |= in mvsaction()
2348 cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; in mvsaction()
2349 // if (ch->pm_level) in mvsaction()
2350 // cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; in mvsaction()
2351 cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; in mvsaction()
2352 cts->xport_specific.sata.caps &= in mvsaction()
2353 ch->user[ccb->ccb_h.target_id].caps; in mvsaction()
2354 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; in mvsaction()
2356 cts->xport_specific.sata.revision = d->revision; in mvsaction()
2357 cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; in mvsaction()
2358 cts->xport_specific.sata.caps = d->caps; in mvsaction()
2359 if (cts->type == CTS_TYPE_CURRENT_SETTINGS/* && in mvsaction()
2360 (ch->quirks & MVS_Q_GENIIE) == 0*/) in mvsaction()
2361 cts->xport_specific.sata.caps &= ~CTS_SATA_CAPS_H_AN; in mvsaction()
2362 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; in mvsaction()
2364 cts->xport_specific.sata.mode = d->mode; in mvsaction()
2365 cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; in mvsaction()
2366 cts->xport_specific.sata.bytecount = d->bytecount; in mvsaction()
2367 cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; in mvsaction()
2368 cts->xport_specific.sata.pm_present = ch->pm_present; in mvsaction()
2369 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; in mvsaction()
2370 cts->xport_specific.sata.tags = d->tags; in mvsaction()
2371 cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; in mvsaction()
2372 cts->xport_specific.sata.atapi = d->atapi; in mvsaction()
2373 cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; in mvsaction()
2374 ccb->ccb_h.status = CAM_REQ_CMP; in mvsaction()
2380 ccb->ccb_h.status = CAM_REQ_CMP; in mvsaction()
2384 ccb->ccb_h.status = CAM_REQ_INVALID; in mvsaction()
2388 struct ccb_pathinq *cpi = &ccb->cpi; in mvsaction()
2391 cpi->version_num = 1; /* XXX??? */ in mvsaction()
2392 cpi->hba_inquiry = PI_SDTR_ABLE; in mvsaction()
2393 if (!(ch->quirks & MVS_Q_GENI)) { in mvsaction()
2394 cpi->hba_inquiry |= PI_SATAPM; in mvsaction()
2395 /* Gen-II is extremely slow with NCQ on PMP. */ in mvsaction()
2396 if ((ch->quirks & MVS_Q_GENIIE) || ch->pm_present == 0) in mvsaction()
2397 cpi->hba_inquiry |= PI_TAG_ABLE; in mvsaction()
2399 cpi->target_sprt = 0; in mvsaction()
2400 cpi->hba_misc = PIM_SEQSCAN; in mvsaction()
2401 cpi->hba_eng_cnt = 0; in mvsaction()
2402 if (!(ch->quirks & MVS_Q_GENI)) in mvsaction()
2403 cpi->max_target = 15; in mvsaction()
2405 cpi->max_target = 0; in mvsaction()
2406 cpi->max_lun = 0; in mvsaction()
2407 cpi->initiator_id = 0; in mvsaction()
2408 cpi->bus_id = cam_sim_bus(sim); in mvsaction()
2409 cpi->base_transfer_speed = 150000; in mvsaction()
2410 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); in mvsaction()
2411 strlcpy(cpi->hba_vid, "Marvell", HBA_IDLEN); in mvsaction()
2412 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); in mvsaction()
2413 cpi->unit_number = cam_sim_unit(sim); in mvsaction()
2414 cpi->transport = XPORT_SATA; in mvsaction()
2415 cpi->transport_version = XPORT_VERSION_UNSPECIFIED; in mvsaction()
2416 cpi->protocol = PROTO_ATA; in mvsaction()
2417 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; in mvsaction()
2418 cpi->maxio = maxphys; in mvsaction()
2419 if ((ch->quirks & MVS_Q_SOC) == 0) { in mvsaction()
2420 cpi->hba_vendor = pci_get_vendor(parent); in mvsaction()
2421 cpi->hba_device = pci_get_device(parent); in mvsaction()
2422 cpi->hba_subvendor = pci_get_subvendor(parent); in mvsaction()
2423 cpi->hba_subdevice = pci_get_subdevice(parent); in mvsaction()
2425 cpi->ccb_h.status = CAM_REQ_CMP; in mvsaction()
2429 ccb->ccb_h.status = CAM_REQ_INVALID; in mvsaction()
2441 arg.arg = ch->dev; in mvspoll()
2444 if (ch->resetting != 0 && in mvspoll()
2445 (--ch->resetpolldiv <= 0 || !callout_pending(&ch->reset_timer))) { in mvspoll()
2446 ch->resetpolldiv = 1000; in mvspoll()
2447 mvs_reset_to(ch->dev); in mvspoll()