Lines Matching +full:fis +full:- +full:based

1 /*-
2 * Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org>
149 /* Command tables. Up to 32 commands, Each, 4-byte aligned. */
158 ((ch->dma.work_bus + FSL_SATA_CT_OFFSET + (FSL_SATA_CT_SIZE * slot->slot)))
161 ((struct fsl_sata_cmd_tab *)(ch->dma.work + FSL_SATA_CT_OFFSET + \
162 (FSL_SATA_CT_SIZE * slot->slot)))
164 ((struct fsl_sata_cmd_list *) (ch->dma.work + FSL_SATA_CL_OFFSET + \
165 (FSL_SATA_CL_SIZE * slot->slot)))
171 uint32_t dwc_flg; /* 0 based */
280 int resetting; /* Hard-reset in progress. */
281 int resetpolldiv; /* Hard-reset poll divider. */
284 struct callout reset_timer; /* Hard-reset timeout */
286 struct fsl_sata_device user[16]; /* User-specified settings */
315 if (!ofw_bus_is_compatible(dev, "fsl,pq-sata-v2") && in fsl_sata_probe()
316 !ofw_bus_is_compatible(dev, "fsl,pq-sata")) in fsl_sata_probe()
330 ch->dev = dev; in fsl_sata_attach()
331 mtx_init(&ch->mtx, "FSL SATA channel lock", NULL, MTX_DEF); in fsl_sata_attach()
332 ch->pm_level = 0; in fsl_sata_attach()
334 device_get_unit(dev), "pm_level", &ch->pm_level); in fsl_sata_attach()
335 STAILQ_INIT(&ch->doneq); in fsl_sata_attach()
336 if (ch->pm_level > 3) in fsl_sata_attach()
337 callout_init_mtx(&ch->pm_timer, &ch->mtx, 0); in fsl_sata_attach()
341 ch->user[i].revision = sata_rev; in fsl_sata_attach()
342 ch->user[i].mode = 0; in fsl_sata_attach()
343 ch->user[i].bytecount = 8192; in fsl_sata_attach()
344 ch->user[i].tags = FSL_SATA_MAX_SLOTS; in fsl_sata_attach()
345 ch->user[i].caps = 0; in fsl_sata_attach()
346 ch->curr[i] = ch->user[i]; in fsl_sata_attach()
347 if (ch->pm_level) { in fsl_sata_attach()
348 ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ | in fsl_sata_attach()
351 ch->user[i].caps |= CTS_SATA_CAPS_H_AN; in fsl_sata_attach()
353 ch->r_mid = 0; in fsl_sata_attach()
354 if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, in fsl_sata_attach()
355 &ch->r_mid, RF_ACTIVE | RF_LITTLEENDIAN))) in fsl_sata_attach()
361 if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, in fsl_sata_attach()
367 if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL, in fsl_sata_attach()
368 fsl_sata_intr, ch, &ch->ih))) { in fsl_sata_attach()
373 mtx_lock(&ch->mtx); in fsl_sata_attach()
382 ch->sim = cam_sim_alloc(fsl_sataaction, fsl_satapoll, "fslsata", ch, in fsl_sata_attach()
383 device_get_unit(dev), (struct mtx *)&ch->mtx, 2, FSL_SATA_MAX_SLOTS, in fsl_sata_attach()
385 if (ch->sim == NULL) { in fsl_sata_attach()
391 if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) { in fsl_sata_attach()
396 if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim), in fsl_sata_attach()
402 if (ch->pm_level > 3) { in fsl_sata_attach()
403 callout_reset(&ch->pm_timer, in fsl_sata_attach()
404 (ch->pm_level == 4) ? hz / 1000 : hz / 8, in fsl_sata_attach()
407 mtx_unlock(&ch->mtx); in fsl_sata_attach()
411 xpt_bus_deregister(cam_sim_path(ch->sim)); in fsl_sata_attach()
413 cam_sim_free(ch->sim, /*free_devq*/TRUE); in fsl_sata_attach()
415 mtx_unlock(&ch->mtx); in fsl_sata_attach()
416 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); in fsl_sata_attach()
418 bus_release_resource(dev, SYS_RES_MEMORY, ch->r_mid, ch->r_mem); in fsl_sata_attach()
419 mtx_destroy(&ch->mtx); in fsl_sata_attach()
428 mtx_lock(&ch->mtx); in fsl_sata_detach()
429 xpt_async(AC_LOST_DEVICE, ch->path, NULL); in fsl_sata_detach()
431 xpt_free_path(ch->path); in fsl_sata_detach()
432 xpt_bus_deregister(cam_sim_path(ch->sim)); in fsl_sata_detach()
433 cam_sim_free(ch->sim, /*free_devq*/TRUE); in fsl_sata_detach()
434 mtx_unlock(&ch->mtx); in fsl_sata_detach()
436 if (ch->pm_level > 3) in fsl_sata_detach()
437 callout_drain(&ch->pm_timer); in fsl_sata_detach()
438 bus_teardown_intr(dev, ch->r_irq, ch->ih); in fsl_sata_detach()
439 bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); in fsl_sata_detach()
445 bus_release_resource(dev, SYS_RES_MEMORY, ch->r_mid, ch->r_mem); in fsl_sata_detach()
446 mtx_destroy(&ch->mtx); in fsl_sata_detach()
457 while (((rval = ATA_INL(ch->r_mem, off)) & mask) != val) { in fsl_sata_wait_register()
475 r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); in fsl_sata_init()
478 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_INT_MASK); in fsl_sata_init()
482 work = ch->dma.work_bus + FSL_SATA_CL_OFFSET; in fsl_sata_init()
483 ATA_OUTL(ch->r_mem, FSL_SATA_P_CHBA, work); in fsl_sata_init()
486 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r); in fsl_sata_init()
487 r = ATA_INL(ch->r_mem, FSL_SATA_P_PCC); in fsl_sata_init()
488 ATA_OUTL(ch->r_mem, FSL_SATA_P_PCC, r & ~FSL_SATA_PCC_LPB_EN); in fsl_sata_init()
489 ATA_OUTL(ch->r_mem, FSL_SATA_P_ICC, (1 << FSL_SATA_P_ICC_ITC_S)); in fsl_sata_init()
501 r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); in fsl_sata_deinit()
502 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_INT_MASK); in fsl_sata_deinit()
506 ATA_OUTL(ch->r_mem, FSL_SATA_P_SCTL, 0); in fsl_sata_deinit()
509 ATA_OUTL(ch->r_mem, FSL_SATA_P_SCTL, ATA_SC_DET_DISABLE); in fsl_sata_deinit()
510 r = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); in fsl_sata_deinit()
512 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, r & ~FSL_SATA_P_HCTRL_HC_ON); in fsl_sata_deinit()
521 mtx_lock(&ch->mtx); in fsl_sata_suspend()
522 xpt_freeze_simq(ch->sim, 1); in fsl_sata_suspend()
523 while (ch->oslots) in fsl_sata_suspend()
524 msleep(ch, &ch->mtx, PRIBIO, "fsl_satasusp", hz/100); in fsl_sata_suspend()
526 mtx_unlock(&ch->mtx); in fsl_sata_suspend()
535 mtx_lock(&ch->mtx); in fsl_sata_resume()
538 xpt_release_simq(ch->sim, TRUE); in fsl_sata_resume()
539 mtx_unlock(&ch->mtx); in fsl_sata_resume()
575 0, NULL, NULL, &ch->dma.work_tag)) in fsl_sata_dmainit()
577 if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work, in fsl_sata_dmainit()
578 BUS_DMA_ZERO, &ch->dma.work_map)) in fsl_sata_dmainit()
580 if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work, in fsl_sata_dmainit()
582 bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); in fsl_sata_dmainit()
585 ch->dma.work_bus = dcba.maddr; in fsl_sata_dmainit()
590 FSL_SATA_SG_ENTRIES - 1, FSL_SATA_PRD_MAX, in fsl_sata_dmainit()
591 0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) { in fsl_sata_dmainit()
595 device_printf(dev, "work area: %p\n", ch->dma.work); in fsl_sata_dmainit()
599 device_printf(dev, "WARNING - DMA initialization failed\n"); in fsl_sata_dmainit()
608 if (!(dcba->error = error)) in fsl_sata_dmasetupc_cb()
609 dcba->maddr = segs[0].ds_addr; in fsl_sata_dmasetupc_cb()
617 if (ch->dma.data_tag) { in fsl_sata_dmafini()
618 bus_dma_tag_destroy(ch->dma.data_tag); in fsl_sata_dmafini()
619 ch->dma.data_tag = NULL; in fsl_sata_dmafini()
621 if (ch->dma.work_bus) { in fsl_sata_dmafini()
622 bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map); in fsl_sata_dmafini()
623 bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map); in fsl_sata_dmafini()
624 ch->dma.work_bus = 0; in fsl_sata_dmafini()
625 ch->dma.work = NULL; in fsl_sata_dmafini()
627 if (ch->dma.work_tag) { in fsl_sata_dmafini()
628 bus_dma_tag_destroy(ch->dma.work_tag); in fsl_sata_dmafini()
629 ch->dma.work_tag = NULL; in fsl_sata_dmafini()
640 bzero(ch->slot, sizeof(ch->slot)); in fsl_sata_slotsalloc()
642 struct fsl_sata_slot *slot = &ch->slot[i]; in fsl_sata_slotsalloc()
644 slot->ch = ch; in fsl_sata_slotsalloc()
645 slot->slot = i; in fsl_sata_slotsalloc()
646 slot->state = FSL_SATA_SLOT_EMPTY; in fsl_sata_slotsalloc()
647 slot->ccb = NULL; in fsl_sata_slotsalloc()
648 callout_init_mtx(&slot->timeout, &ch->mtx, 0); in fsl_sata_slotsalloc()
650 if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map)) in fsl_sata_slotsalloc()
651 device_printf(ch->dev, "FAILURE - create data_map\n"); in fsl_sata_slotsalloc()
663 struct fsl_sata_slot *slot = &ch->slot[i]; in fsl_sata_slotsfree()
665 callout_drain(&slot->timeout); in fsl_sata_slotsfree()
666 if (slot->dma.data_map) { in fsl_sata_slotsfree()
667 bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); in fsl_sata_slotsfree()
668 slot->dma.data_map = NULL; in fsl_sata_slotsfree()
677 if (((ch->pm_level == 0) && (serr & ATA_SE_PHY_CHANGED)) || in fsl_sata_phy_check_events()
678 ((ch->pm_level != 0) && (serr & ATA_SE_EXCHANGED))) { in fsl_sata_phy_check_events()
679 u_int32_t status = ATA_INL(ch->r_mem, FSL_SATA_P_SSTS); in fsl_sata_phy_check_events()
684 device_printf(ch->dev, "CONNECT requested\n"); in fsl_sata_phy_check_events()
686 device_printf(ch->dev, "DISCONNECT requested\n"); in fsl_sata_phy_check_events()
689 xpt_async(AC_BUS_RESET, ch->path, NULL); in fsl_sata_phy_check_events()
692 if (xpt_create_path(&ccb->ccb_h.path, NULL, in fsl_sata_phy_check_events()
693 cam_sim_path(ch->sim), in fsl_sata_phy_check_events()
710 ATA_OUTL(ch->r_mem, FSL_SATA_P_SNTF, status); in fsl_sata_notify_events()
712 device_printf(ch->dev, "SNTF 0x%04x\n", status); in fsl_sata_notify_events()
717 xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) { in fsl_sata_notify_events()
728 mtx_assert(&ch->mtx, MA_OWNED); in fsl_sata_done()
729 if ((ccb->ccb_h.func_code & XPT_FC_QUEUED) == 0 || in fsl_sata_done()
730 ch->batch == 0) { in fsl_sata_done()
735 STAILQ_INSERT_TAIL(&ch->doneq, &ccb->ccb_h, sim_links.stqe); in fsl_sata_done()
747 istatus = ATA_INL(ch->r_mem, FSL_SATA_P_HSTS) & 0x7ffff; in fsl_sata_intr()
751 mtx_lock(&ch->mtx); in fsl_sata_intr()
752 ch->batch = 1; in fsl_sata_intr()
754 ch->batch = 0; in fsl_sata_intr()
759 STAILQ_CONCAT(&tmp_doneq, &ch->doneq); in fsl_sata_intr()
760 mtx_unlock(&ch->mtx); in fsl_sata_intr()
766 ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, istatus & 0x3f); in fsl_sata_intr()
776 if (ch->numrslots != 0) in fsl_sata_pm()
778 work = ATA_INL(ch->r_mem, FSL_SATA_P_PCC) & ~FSL_SATA_PCC_LPB_EN; in fsl_sata_pm()
779 if (ch->pm_level == 4) in fsl_sata_pm()
783 ATA_OUTL(ch->r_mem, FSL_SATA_P_PCC, work); in fsl_sata_pm()
795 ok = ATA_INL(ch->r_mem, FSL_SATA_P_CCR); in fsl_sata_intr_main()
797 ATA_OUTL(ch->r_mem, FSL_SATA_P_CCR, ok); in fsl_sata_intr_main()
798 if (ch->aslots == 0 && ok != 0) { in fsl_sata_intr_main()
800 if (((ok >> i) & 1) && ch->slot[i].ccb != NULL) in fsl_sata_intr_main()
801 fsl_sata_end_transaction(&ch->slot[i], in fsl_sata_intr_main()
807 sntf = ATA_INL(ch->r_mem, FSL_SATA_P_SNTF); in fsl_sata_intr_main()
809 serr = ATA_INL(ch->r_mem, FSL_SATA_P_SERR); in fsl_sata_intr_main()
810 ATA_OUTL(ch->r_mem, FSL_SATA_P_SERR, serr); in fsl_sata_intr_main()
818 cer = ATA_INL(ch->r_mem, FSL_SATA_P_CER); in fsl_sata_intr_main()
819 ATA_OUTL(ch->r_mem, FSL_SATA_P_CER, cer); in fsl_sata_intr_main()
820 der = ATA_INL(ch->r_mem, FSL_SATA_P_DER); in fsl_sata_intr_main()
821 ATA_OUTL(ch->r_mem, FSL_SATA_P_DER, der); in fsl_sata_intr_main()
824 if (ch->frozen) { in fsl_sata_intr_main()
825 union ccb *fccb = ch->frozen; in fsl_sata_intr_main()
826 ch->frozen = NULL; in fsl_sata_intr_main()
827 fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; in fsl_sata_intr_main()
828 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { in fsl_sata_intr_main()
829 xpt_freeze_devq(fccb->ccb_h.path, 1); in fsl_sata_intr_main()
830 fccb->ccb_h.status |= CAM_DEV_QFRZN; in fsl_sata_intr_main()
835 if (ch->slot[i].ccb == NULL) in fsl_sata_intr_main()
839 else if ((der & (1 << ch->slot[i].ccb->ccb_h.target_id)) != 0) in fsl_sata_intr_main()
843 fsl_sata_end_transaction(&ch->slot[i], et); in fsl_sata_intr_main()
855 int t = ccb->ccb_h.target_id; in fsl_sata_check_collision()
857 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_check_collision()
858 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { in fsl_sata_check_collision()
860 if (((~ch->oslots) & (0xffff >> (16 - ch->curr[t].tags))) == 0) in fsl_sata_check_collision()
863 if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] == 0) in fsl_sata_check_collision()
867 if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] != 0) in fsl_sata_check_collision()
870 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_check_collision()
871 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { in fsl_sata_check_collision()
873 if (ch->numrslots != 0) in fsl_sata_check_collision()
877 if (ch->aslots != 0) in fsl_sata_check_collision()
889 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, in fsl_sata_begin_transaction()
890 ("fsl_sata_begin_transaction func_code=0x%x\n", ccb->ccb_h.func_code)); in fsl_sata_begin_transaction()
893 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_begin_transaction()
894 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) in fsl_sata_begin_transaction()
895 tags = ch->curr[ccb->ccb_h.target_id].tags; in fsl_sata_begin_transaction()
896 if (ch->lastslot + 1 < tags) in fsl_sata_begin_transaction()
897 tag = ffs(~(ch->oslots >> (ch->lastslot + 1))); in fsl_sata_begin_transaction()
900 if (tag == 0 || tag + ch->lastslot >= tags) in fsl_sata_begin_transaction()
901 tag = ffs(~ch->oslots) - 1; in fsl_sata_begin_transaction()
903 tag += ch->lastslot; in fsl_sata_begin_transaction()
904 ch->lastslot = tag; in fsl_sata_begin_transaction()
906 slot = &ch->slot[tag]; in fsl_sata_begin_transaction()
907 slot->ccb = ccb; in fsl_sata_begin_transaction()
908 slot->ttl = 0; in fsl_sata_begin_transaction()
910 if (ch->numrslots == 0 && ch->pm_level > 3) in fsl_sata_begin_transaction()
911 callout_stop(&ch->pm_timer); in fsl_sata_begin_transaction()
913 ch->oslots |= (1 << tag); in fsl_sata_begin_transaction()
914 ch->numrslots++; in fsl_sata_begin_transaction()
915 ch->numrslotspd[ccb->ccb_h.target_id]++; in fsl_sata_begin_transaction()
916 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_begin_transaction()
917 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { in fsl_sata_begin_transaction()
918 ch->numtslots++; in fsl_sata_begin_transaction()
919 ch->numtslotspd[ccb->ccb_h.target_id]++; in fsl_sata_begin_transaction()
920 ch->taggedtarget = ccb->ccb_h.target_id; in fsl_sata_begin_transaction()
922 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_begin_transaction()
923 (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) in fsl_sata_begin_transaction()
924 ch->aslots |= (1 << tag); in fsl_sata_begin_transaction()
925 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in fsl_sata_begin_transaction()
926 slot->state = FSL_SATA_SLOT_LOADING; in fsl_sata_begin_transaction()
927 bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, ccb, in fsl_sata_begin_transaction()
930 slot->dma.nsegs = 0; in fsl_sata_begin_transaction()
934 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, in fsl_sata_begin_transaction()
943 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_dmasetprd()
949 device_printf(ch->dev, "DMA load error %d\n", error); in fsl_sata_dmasetprd()
953 KASSERT(nsegs <= FSL_SATA_SG_ENTRIES - 1, in fsl_sata_dmasetprd()
958 prd = &ctp->prd_tab[0]; in fsl_sata_dmasetprd()
971 slot->ttl += len; in fsl_sata_dmasetprd()
975 slot->dma.nsegs = j; in fsl_sata_dmasetprd()
979 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, in fsl_sata_dmasetprd()
980 ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ? in fsl_sata_dmasetprd()
989 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_execute_transaction()
992 union ccb *ccb = slot->ccb; in fsl_sata_execute_transaction()
993 int port = ccb->ccb_h.target_id & 0x0f; in fsl_sata_execute_transaction()
999 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, in fsl_sata_execute_transaction()
1000 ("fsl_sata_execute_transaction func_code=0x%x\n", ccb->ccb_h.func_code)); in fsl_sata_execute_transaction()
1003 /* Setup the FIS for this request */ in fsl_sata_execute_transaction()
1004 if (!(fis_size = fsl_sata_setup_fis(ch, ctp, ccb, slot->slot))) { in fsl_sata_execute_transaction()
1005 device_printf(ch->dev, "Setting up SATA FIS failed\n"); in fsl_sata_execute_transaction()
1011 clp->fis_length = htole16(fis_size); in fsl_sata_execute_transaction()
1012 clp->prd_length = htole16(slot->dma.nsegs); in fsl_sata_execute_transaction()
1014 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_execute_transaction()
1015 (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { in fsl_sata_execute_transaction()
1016 if (ccb->ataio.cmd.control & ATA_A_RESET) { in fsl_sata_execute_transaction()
1020 /* Prepare FIS receive area for check. */ in fsl_sata_execute_transaction()
1022 ctp->sfis[i] = 0xff; in fsl_sata_execute_transaction()
1026 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) in fsl_sata_execute_transaction()
1028 clp->cmd_flags = htole32(cmd_flags | in fsl_sata_execute_transaction()
1029 (ccb->ccb_h.func_code == XPT_SCSI_IO ? FSL_SATA_CMD_ATAPI : 0) | in fsl_sata_execute_transaction()
1030 slot->slot); in fsl_sata_execute_transaction()
1031 clp->ttl = htole32(slot->ttl); in fsl_sata_execute_transaction()
1032 clp->cda = htole32(FSL_SATA_CTP_BUS(ch, slot)); in fsl_sata_execute_transaction()
1033 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, in fsl_sata_execute_transaction()
1036 slot->state = FSL_SATA_SLOT_RUNNING; in fsl_sata_execute_transaction()
1037 ch->rslots |= (1 << slot->slot); in fsl_sata_execute_transaction()
1038 ATA_OUTL(ch->r_mem, FSL_SATA_P_CQPMP, port); in fsl_sata_execute_transaction()
1039 ATA_OUTL(ch->r_mem, FSL_SATA_P_CQR, (1 << slot->slot)); in fsl_sata_execute_transaction()
1041 if (ccb->ccb_h.func_code == XPT_ATA_IO && in fsl_sata_execute_transaction()
1042 (ccb->ataio.cmd.command == ATA_DEVICE_RESET || softreset)) { in fsl_sata_execute_transaction()
1043 int count, timeout = ccb->ccb_h.timeout * 100; in fsl_sata_execute_transaction()
1050 tmp = ATA_INL(ch->r_mem, FSL_SATA_P_SIG); in fsl_sata_execute_transaction()
1055 if ((ATA_INL(ch->r_mem, FSL_SATA_P_CCR) & (1 << slot->slot)) != 0) in fsl_sata_execute_transaction()
1060 device_printf(ch->dev, "Poll timeout on slot %d port %d (round %d)\n", in fsl_sata_execute_transaction()
1061 slot->slot, port, softreset); in fsl_sata_execute_transaction()
1062 device_printf(ch->dev, "hsts %08x cqr %08x ccr %08x ss %08x " in fsl_sata_execute_transaction()
1064 ATA_INL(ch->r_mem, FSL_SATA_P_HSTS), in fsl_sata_execute_transaction()
1065 ATA_INL(ch->r_mem, FSL_SATA_P_CQR), in fsl_sata_execute_transaction()
1066 ATA_INL(ch->r_mem, FSL_SATA_P_CCR), in fsl_sata_execute_transaction()
1067 ATA_INL(ch->r_mem, FSL_SATA_P_SSTS), ch->rslots, in fsl_sata_execute_transaction()
1068 ATA_INL(ch->r_mem, FSL_SATA_P_CER), in fsl_sata_execute_transaction()
1069 ATA_INL(ch->r_mem, FSL_SATA_P_DER), in fsl_sata_execute_transaction()
1070 ATA_INL(ch->r_mem, FSL_SATA_P_SERR), in fsl_sata_execute_transaction()
1071 ATA_INL(ch->r_mem, FSL_SATA_P_CAR), in fsl_sata_execute_transaction()
1072 ATA_INL(ch->r_mem, FSL_SATA_P_SIG)); in fsl_sata_execute_transaction()
1080 callout_reset_sbt(&slot->timeout, SBT_1MS * ccb->ccb_h.timeout / 2, in fsl_sata_execute_transaction()
1091 mtx_assert(&ch->mtx, MA_OWNED); in fsl_sata_process_timeout()
1095 if (ch->slot[i].state < FSL_SATA_SLOT_RUNNING) in fsl_sata_process_timeout()
1097 fsl_sata_end_transaction(&ch->slot[i], FSL_SATA_ERR_TIMEOUT); in fsl_sata_process_timeout()
1107 mtx_assert(&ch->mtx, MA_OWNED); in fsl_sata_rearm_timeout()
1109 struct fsl_sata_slot *slot = &ch->slot[i]; in fsl_sata_rearm_timeout()
1112 if (slot->state < FSL_SATA_SLOT_RUNNING) in fsl_sata_rearm_timeout()
1114 if ((ch->toslots & (1 << i)) == 0) in fsl_sata_rearm_timeout()
1116 callout_reset_sbt(&slot->timeout, in fsl_sata_rearm_timeout()
1117 SBT_1MS * slot->ccb->ccb_h.timeout / 2, 0, in fsl_sata_rearm_timeout()
1127 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_timeout()
1128 device_t dev = ch->dev; in fsl_sata_timeout()
1132 if (slot->state < FSL_SATA_SLOT_RUNNING) in fsl_sata_timeout()
1136 if (slot->state < FSL_SATA_SLOT_EXECUTING) { in fsl_sata_timeout()
1138 sstatus = ATA_INL(ch->r_mem, FSL_SATA_P_CAR); in fsl_sata_timeout()
1139 if ((sstatus & (1 << slot->slot)) != 0) in fsl_sata_timeout()
1140 slot->state = FSL_SATA_SLOT_EXECUTING; in fsl_sata_timeout()
1142 callout_reset_sbt(&slot->timeout, in fsl_sata_timeout()
1143 SBT_1MS * slot->ccb->ccb_h.timeout / 2, 0, in fsl_sata_timeout()
1149 slot->slot, slot->ccb->ccb_h.target_id & 0x0f); in fsl_sata_timeout()
1152 if (ch->frozen) { in fsl_sata_timeout()
1153 union ccb *fccb = ch->frozen; in fsl_sata_timeout()
1154 ch->frozen = NULL; in fsl_sata_timeout()
1155 fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; in fsl_sata_timeout()
1156 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { in fsl_sata_timeout()
1157 xpt_freeze_devq(fccb->ccb_h.path, 1); in fsl_sata_timeout()
1158 fccb->ccb_h.status |= CAM_DEV_QFRZN; in fsl_sata_timeout()
1162 if (ch->toslots == 0) in fsl_sata_timeout()
1163 xpt_freeze_simq(ch->sim, 1); in fsl_sata_timeout()
1164 ch->toslots |= (1 << slot->slot); in fsl_sata_timeout()
1165 if ((ch->rslots & ~ch->toslots) == 0) in fsl_sata_timeout()
1169 ch->rslots & ~ch->toslots); in fsl_sata_timeout()
1176 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_end_transaction()
1177 union ccb *ccb = slot->ccb; in fsl_sata_end_transaction()
1182 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, in fsl_sata_end_transaction()
1186 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in fsl_sata_end_transaction()
1187 struct ata_res *res = &ccb->ataio.res; in fsl_sata_end_transaction()
1190 (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { in fsl_sata_end_transaction()
1192 uint8_t *fis = ctp->sfis; in fsl_sata_end_transaction() local
1194 res->status = fis[2]; in fsl_sata_end_transaction()
1195 res->error = fis[3]; in fsl_sata_end_transaction()
1196 res->lba_low = fis[4]; in fsl_sata_end_transaction()
1197 res->lba_mid = fis[5]; in fsl_sata_end_transaction()
1198 res->lba_high = fis[6]; in fsl_sata_end_transaction()
1199 res->device = fis[7]; in fsl_sata_end_transaction()
1200 res->lba_low_exp = fis[8]; in fsl_sata_end_transaction()
1201 res->lba_mid_exp = fis[9]; in fsl_sata_end_transaction()
1202 res->lba_high_exp = fis[10]; in fsl_sata_end_transaction()
1203 res->sector_count = fis[12]; in fsl_sata_end_transaction()
1204 res->sector_count_exp = fis[13]; in fsl_sata_end_transaction()
1206 if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && in fsl_sata_end_transaction()
1207 (ccb->ataio.cmd.control & ATA_A_RESET) == 0) { in fsl_sata_end_transaction()
1208 sig = ATA_INL(ch->r_mem, FSL_SATA_P_SIG); in fsl_sata_end_transaction()
1209 res->lba_high = sig >> 24; in fsl_sata_end_transaction()
1210 res->lba_mid = sig >> 16; in fsl_sata_end_transaction()
1211 res->lba_low = sig >> 8; in fsl_sata_end_transaction()
1212 res->sector_count = sig; in fsl_sata_end_transaction()
1216 if ((ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) == 0 && in fsl_sata_end_transaction()
1217 (ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in fsl_sata_end_transaction()
1218 ccb->ataio.resid = in fsl_sata_end_transaction()
1219 ccb->ataio.dxfer_len - le32toh(clp->ttl); in fsl_sata_end_transaction()
1222 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in fsl_sata_end_transaction()
1223 ccb->csio.resid = in fsl_sata_end_transaction()
1224 ccb->csio.dxfer_len - le32toh(clp->ttl); in fsl_sata_end_transaction()
1227 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { in fsl_sata_end_transaction()
1228 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, in fsl_sata_end_transaction()
1229 (ccb->ccb_h.flags & CAM_DIR_IN) ? in fsl_sata_end_transaction()
1231 bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map); in fsl_sata_end_transaction()
1234 ch->eslots |= (1 << slot->slot); in fsl_sata_end_transaction()
1236 if ((et != FSL_SATA_ERR_NONE) && (!ch->recoverycmd) && in fsl_sata_end_transaction()
1237 !(ccb->ccb_h.status & CAM_DEV_QFRZN)) { in fsl_sata_end_transaction()
1238 xpt_freeze_devq(ccb->ccb_h.path, 1); in fsl_sata_end_transaction()
1239 ccb->ccb_h.status |= CAM_DEV_QFRZN; in fsl_sata_end_transaction()
1242 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_end_transaction()
1245 ccb->ccb_h.status |= CAM_REQ_CMP; in fsl_sata_end_transaction()
1246 if (ccb->ccb_h.func_code == XPT_SCSI_IO) in fsl_sata_end_transaction()
1247 ccb->csio.scsi_status = SCSI_STATUS_OK; in fsl_sata_end_transaction()
1250 ch->fatalerr = 1; in fsl_sata_end_transaction()
1251 ccb->ccb_h.status |= CAM_REQ_INVALID; in fsl_sata_end_transaction()
1254 ccb->ccb_h.status |= CAM_REQUEUE_REQ; in fsl_sata_end_transaction()
1258 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in fsl_sata_end_transaction()
1259 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; in fsl_sata_end_transaction()
1260 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; in fsl_sata_end_transaction()
1262 ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR; in fsl_sata_end_transaction()
1266 ch->fatalerr = 1; in fsl_sata_end_transaction()
1267 if (!ch->recoverycmd) { in fsl_sata_end_transaction()
1268 xpt_freeze_simq(ch->sim, 1); in fsl_sata_end_transaction()
1269 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_end_transaction()
1270 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; in fsl_sata_end_transaction()
1272 ccb->ccb_h.status |= CAM_UNCOR_PARITY; in fsl_sata_end_transaction()
1275 if (!ch->recoverycmd) { in fsl_sata_end_transaction()
1276 xpt_freeze_simq(ch->sim, 1); in fsl_sata_end_transaction()
1277 ccb->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_end_transaction()
1278 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; in fsl_sata_end_transaction()
1280 ccb->ccb_h.status |= CAM_CMD_TIMEOUT; in fsl_sata_end_transaction()
1283 ch->fatalerr = 1; in fsl_sata_end_transaction()
1284 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; in fsl_sata_end_transaction()
1287 ch->oslots &= ~(1 << slot->slot); in fsl_sata_end_transaction()
1288 ch->rslots &= ~(1 << slot->slot); in fsl_sata_end_transaction()
1289 ch->aslots &= ~(1 << slot->slot); in fsl_sata_end_transaction()
1290 slot->state = FSL_SATA_SLOT_EMPTY; in fsl_sata_end_transaction()
1291 slot->ccb = NULL; in fsl_sata_end_transaction()
1293 ch->numrslots--; in fsl_sata_end_transaction()
1294 ch->numrslotspd[ccb->ccb_h.target_id]--; in fsl_sata_end_transaction()
1295 ATA_OUTL(ch->r_mem, FSL_SATA_P_CCR, 1 << slot->slot); in fsl_sata_end_transaction()
1296 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_end_transaction()
1297 (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { in fsl_sata_end_transaction()
1298 ch->numtslots--; in fsl_sata_end_transaction()
1299 ch->numtslotspd[ccb->ccb_h.target_id]--; in fsl_sata_end_transaction()
1303 lastto = (ch->toslots == (1 << slot->slot)); in fsl_sata_end_transaction()
1304 ch->toslots &= ~(1 << slot->slot); in fsl_sata_end_transaction()
1306 xpt_release_simq(ch->sim, TRUE); in fsl_sata_end_transaction()
1310 if ((ccb->ccb_h.func_code == XPT_ATA_IO) && in fsl_sata_end_transaction()
1311 (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && in fsl_sata_end_transaction()
1312 (ccb->ataio.cmd.control & ATA_A_RESET) && in fsl_sata_end_transaction()
1314 ccb->ataio.cmd.control &= ~ATA_A_RESET; in fsl_sata_end_transaction()
1318 /* If it was our READ LOG command - process it. */ in fsl_sata_end_transaction()
1319 if (ccb->ccb_h.recovery_type == RECOVERY_READ_LOG) { in fsl_sata_end_transaction()
1321 /* If it was our REQUEST SENSE command - process it. */ in fsl_sata_end_transaction()
1322 } else if (ccb->ccb_h.recovery_type == RECOVERY_REQUEST_SENSE) { in fsl_sata_end_transaction()
1326 ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR && in fsl_sata_end_transaction()
1327 (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)) { in fsl_sata_end_transaction()
1328 ch->hold[slot->slot] = ccb; in fsl_sata_end_transaction()
1329 ch->numhslots++; in fsl_sata_end_transaction()
1333 if (ch->rslots == 0) { in fsl_sata_end_transaction()
1334 /* if there was fatal error - reset port. */ in fsl_sata_end_transaction()
1335 if (ch->toslots != 0 || ch->fatalerr) { in fsl_sata_end_transaction()
1339 if (ch->eslots != 0) { in fsl_sata_end_transaction()
1344 if (!ch->recoverycmd && ch->numhslots) in fsl_sata_end_transaction()
1347 /* If all the rest of commands are in timeout - give them chance. */ in fsl_sata_end_transaction()
1348 } else if ((ch->rslots & ~ch->toslots) == 0 && in fsl_sata_end_transaction()
1352 if (ch->frozen && !fsl_sata_check_collision(ch, ch->frozen)) { in fsl_sata_end_transaction()
1353 union ccb *fccb = ch->frozen; in fsl_sata_end_transaction()
1354 ch->frozen = NULL; in fsl_sata_end_transaction()
1356 xpt_release_simq(ch->sim, TRUE); in fsl_sata_end_transaction()
1359 if (ch->numrslots == 0 && ch->pm_level > 3 && in fsl_sata_end_transaction()
1360 (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) { in fsl_sata_end_transaction()
1361 callout_schedule(&ch->pm_timer, in fsl_sata_end_transaction()
1362 (ch->pm_level == 4) ? hz / 1000 : hz / 8); in fsl_sata_end_transaction()
1376 if (ch->hold[i]) in fsl_sata_issue_recovery()
1381 device_printf(ch->dev, "Unable to allocate recovery command\n"); in fsl_sata_issue_recovery()
1383 /* We can't do anything -- complete held commands. */ in fsl_sata_issue_recovery()
1385 if (ch->hold[i] == NULL) in fsl_sata_issue_recovery()
1387 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_issue_recovery()
1388 ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL; in fsl_sata_issue_recovery()
1389 fsl_sata_done(ch, ch->hold[i]); in fsl_sata_issue_recovery()
1390 ch->hold[i] = NULL; in fsl_sata_issue_recovery()
1391 ch->numhslots--; in fsl_sata_issue_recovery()
1396 ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */ in fsl_sata_issue_recovery()
1397 if (ccb->ccb_h.func_code == XPT_ATA_IO) { in fsl_sata_issue_recovery()
1399 ccb->ccb_h.recovery_type = RECOVERY_READ_LOG; in fsl_sata_issue_recovery()
1400 ccb->ccb_h.func_code = XPT_ATA_IO; in fsl_sata_issue_recovery()
1401 ccb->ccb_h.flags = CAM_DIR_IN; in fsl_sata_issue_recovery()
1402 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ in fsl_sata_issue_recovery()
1403 ataio = &ccb->ataio; in fsl_sata_issue_recovery()
1404 ataio->data_ptr = malloc(512, M_FSL_SATA, M_NOWAIT); in fsl_sata_issue_recovery()
1405 if (ataio->data_ptr == NULL) { in fsl_sata_issue_recovery()
1407 device_printf(ch->dev, in fsl_sata_issue_recovery()
1411 ataio->dxfer_len = 512; in fsl_sata_issue_recovery()
1412 bzero(&ataio->cmd, sizeof(ataio->cmd)); in fsl_sata_issue_recovery()
1413 ataio->cmd.flags = CAM_ATAIO_48BIT; in fsl_sata_issue_recovery()
1414 ataio->cmd.command = 0x2F; /* READ LOG EXT */ in fsl_sata_issue_recovery()
1415 ataio->cmd.sector_count = 1; in fsl_sata_issue_recovery()
1416 ataio->cmd.sector_count_exp = 0; in fsl_sata_issue_recovery()
1417 ataio->cmd.lba_low = 0x10; in fsl_sata_issue_recovery()
1418 ataio->cmd.lba_mid = 0; in fsl_sata_issue_recovery()
1419 ataio->cmd.lba_mid_exp = 0; in fsl_sata_issue_recovery()
1422 ccb->ccb_h.recovery_type = RECOVERY_REQUEST_SENSE; in fsl_sata_issue_recovery()
1423 ccb->ccb_h.recovery_slot = i; in fsl_sata_issue_recovery()
1424 ccb->ccb_h.func_code = XPT_SCSI_IO; in fsl_sata_issue_recovery()
1425 ccb->ccb_h.flags = CAM_DIR_IN; in fsl_sata_issue_recovery()
1426 ccb->ccb_h.status = 0; in fsl_sata_issue_recovery()
1427 ccb->ccb_h.timeout = 1000; /* 1s should be enough. */ in fsl_sata_issue_recovery()
1428 csio = &ccb->csio; in fsl_sata_issue_recovery()
1429 csio->data_ptr = (void *)&ch->hold[i]->csio.sense_data; in fsl_sata_issue_recovery()
1430 csio->dxfer_len = ch->hold[i]->csio.sense_len; in fsl_sata_issue_recovery()
1431 csio->cdb_len = 6; in fsl_sata_issue_recovery()
1432 bzero(&csio->cdb_io, sizeof(csio->cdb_io)); in fsl_sata_issue_recovery()
1433 csio->cdb_io.cdb_bytes[0] = 0x03; in fsl_sata_issue_recovery()
1434 csio->cdb_io.cdb_bytes[4] = csio->dxfer_len; in fsl_sata_issue_recovery()
1437 ch->recoverycmd = 1; in fsl_sata_issue_recovery()
1438 xpt_freeze_simq(ch->sim, 1); in fsl_sata_issue_recovery()
1449 ch->recoverycmd = 0; in fsl_sata_process_read_log()
1451 data = ccb->ataio.data_ptr; in fsl_sata_process_read_log()
1452 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && in fsl_sata_process_read_log()
1455 if (!ch->hold[i]) in fsl_sata_process_read_log()
1457 if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO) in fsl_sata_process_read_log()
1460 res = &ch->hold[i]->ataio.res; in fsl_sata_process_read_log()
1461 res->status = data[2]; in fsl_sata_process_read_log()
1462 res->error = data[3]; in fsl_sata_process_read_log()
1463 res->lba_low = data[4]; in fsl_sata_process_read_log()
1464 res->lba_mid = data[5]; in fsl_sata_process_read_log()
1465 res->lba_high = data[6]; in fsl_sata_process_read_log()
1466 res->device = data[7]; in fsl_sata_process_read_log()
1467 res->lba_low_exp = data[8]; in fsl_sata_process_read_log()
1468 res->lba_mid_exp = data[9]; in fsl_sata_process_read_log()
1469 res->lba_high_exp = data[10]; in fsl_sata_process_read_log()
1470 res->sector_count = data[12]; in fsl_sata_process_read_log()
1471 res->sector_count_exp = data[13]; in fsl_sata_process_read_log()
1473 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_process_read_log()
1474 ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ; in fsl_sata_process_read_log()
1476 fsl_sata_done(ch, ch->hold[i]); in fsl_sata_process_read_log()
1477 ch->hold[i] = NULL; in fsl_sata_process_read_log()
1478 ch->numhslots--; in fsl_sata_process_read_log()
1481 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) in fsl_sata_process_read_log()
1482 device_printf(ch->dev, "Error while READ LOG EXT\n"); in fsl_sata_process_read_log()
1484 device_printf(ch->dev, "Non-queued command error in READ LOG EXT\n"); in fsl_sata_process_read_log()
1487 if (!ch->hold[i]) in fsl_sata_process_read_log()
1489 if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO) in fsl_sata_process_read_log()
1491 fsl_sata_done(ch, ch->hold[i]); in fsl_sata_process_read_log()
1492 ch->hold[i] = NULL; in fsl_sata_process_read_log()
1493 ch->numhslots--; in fsl_sata_process_read_log()
1496 free(ccb->ataio.data_ptr, M_FSL_SATA); in fsl_sata_process_read_log()
1498 xpt_release_simq(ch->sim, TRUE); in fsl_sata_process_read_log()
1506 ch->recoverycmd = 0; in fsl_sata_process_request_sense()
1508 i = ccb->ccb_h.recovery_slot; in fsl_sata_process_request_sense()
1509 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { in fsl_sata_process_request_sense()
1510 ch->hold[i]->ccb_h.status |= CAM_AUTOSNS_VALID; in fsl_sata_process_request_sense()
1512 ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK; in fsl_sata_process_request_sense()
1513 ch->hold[i]->ccb_h.status |= CAM_AUTOSENSE_FAIL; in fsl_sata_process_request_sense()
1515 fsl_sata_done(ch, ch->hold[i]); in fsl_sata_process_request_sense()
1516 ch->hold[i] = NULL; in fsl_sata_process_request_sense()
1517 ch->numhslots--; in fsl_sata_process_request_sense()
1519 xpt_release_simq(ch->sim, TRUE); in fsl_sata_process_request_sense()
1528 ATA_OUTL(ch->r_mem, FSL_SATA_P_SERR, 0xFFFFFFFF); in fsl_sata_start()
1530 ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, 0x3F); in fsl_sata_start()
1531 ATA_OUTL(ch->r_mem, FSL_SATA_P_CER, 0xFFFF); in fsl_sata_start()
1532 ATA_OUTL(ch->r_mem, FSL_SATA_P_DER, 0xFFFF); in fsl_sata_start()
1534 cmd = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); in fsl_sata_start()
1537 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, cmd | in fsl_sata_start()
1538 (ch->pm_present ? FSL_SATA_P_HCTRL_PM : 0)); in fsl_sata_start()
1541 ATA_OUTL(ch->r_mem, FSL_SATA_P_HSTS, in fsl_sata_start()
1542 ATA_INL(ch->r_mem, FSL_SATA_P_HSTS) & FSL_SATA_P_HSTS_PR); in fsl_sata_start()
1552 cmd = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL); in fsl_sata_stop()
1556 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, cmd); in fsl_sata_stop()
1560 device_printf(ch->dev, in fsl_sata_stop()
1566 ch->eslots = 0; in fsl_sata_stop()
1575 xpt_freeze_simq(ch->sim, 1); in fsl_sata_reset()
1577 device_printf(ch->dev, "FSL SATA reset...\n"); in fsl_sata_reset()
1580 if (ch->frozen) { in fsl_sata_reset()
1581 union ccb *fccb = ch->frozen; in fsl_sata_reset()
1582 ch->frozen = NULL; in fsl_sata_reset()
1583 fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ; in fsl_sata_reset()
1584 if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) { in fsl_sata_reset()
1585 xpt_freeze_devq(fccb->ccb_h.path, 1); in fsl_sata_reset()
1586 fccb->ccb_h.status |= CAM_DEV_QFRZN; in fsl_sata_reset()
1595 if (ch->slot[i].state < FSL_SATA_SLOT_RUNNING) in fsl_sata_reset()
1598 fsl_sata_end_transaction(&ch->slot[i], FSL_SATA_ERR_INNOCENT); in fsl_sata_reset()
1601 if (!ch->hold[i]) in fsl_sata_reset()
1603 fsl_sata_done(ch, ch->hold[i]); in fsl_sata_reset()
1604 ch->hold[i] = NULL; in fsl_sata_reset()
1605 ch->numhslots--; in fsl_sata_reset()
1607 if (ch->toslots != 0) in fsl_sata_reset()
1608 xpt_release_simq(ch->sim, TRUE); in fsl_sata_reset()
1609 ch->eslots = 0; in fsl_sata_reset()
1610 ch->toslots = 0; in fsl_sata_reset()
1611 ch->fatalerr = 0; in fsl_sata_reset()
1613 xpt_async(AC_BUS_RESET, ch->path, NULL); in fsl_sata_reset()
1615 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, in fsl_sata_reset()
1616 ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) & ~0x3f); in fsl_sata_reset()
1621 device_printf(ch->dev, in fsl_sata_reset()
1623 ch->devices = 0; in fsl_sata_reset()
1625 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, in fsl_sata_reset()
1626 ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) | FSL_SATA_P_HCTRL_PHYRDY); in fsl_sata_reset()
1627 xpt_release_simq(ch->sim, TRUE); in fsl_sata_reset()
1631 device_printf(ch->dev, "FSL SATA reset: device found\n"); in fsl_sata_reset()
1632 ch->devices = 1; in fsl_sata_reset()
1634 ctrl = ATA_INL(ch->r_mem, FSL_SATA_P_HCTRL) & ~0x3f; in fsl_sata_reset()
1635 ATA_OUTL(ch->r_mem, FSL_SATA_P_HCTRL, in fsl_sata_reset()
1639 xpt_release_simq(ch->sim, TRUE); in fsl_sata_reset()
1645 uint8_t *fis = &ctp->cfis[0]; in fsl_sata_setup_fis() local
1647 bzero(fis, 32); in fsl_sata_setup_fis()
1648 fis[0] = 0x27; /* host to device */ in fsl_sata_setup_fis()
1649 fis[1] = (ccb->ccb_h.target_id & 0x0f); in fsl_sata_setup_fis()
1650 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { in fsl_sata_setup_fis()
1651 fis[1] |= 0x80; in fsl_sata_setup_fis()
1652 fis[2] = ATA_PACKET_CMD; in fsl_sata_setup_fis()
1653 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && in fsl_sata_setup_fis()
1654 ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) in fsl_sata_setup_fis()
1655 fis[3] = ATA_F_DMA; in fsl_sata_setup_fis()
1657 fis[5] = ccb->csio.dxfer_len; in fsl_sata_setup_fis()
1658 fis[6] = ccb->csio.dxfer_len >> 8; in fsl_sata_setup_fis()
1660 fis[7] = ATA_D_LBA; in fsl_sata_setup_fis()
1661 fis[15] = ATA_A_4BIT; in fsl_sata_setup_fis()
1662 bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ? in fsl_sata_setup_fis()
1663 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes, in fsl_sata_setup_fis()
1664 ctp->acmd, ccb->csio.cdb_len); in fsl_sata_setup_fis()
1665 bzero(ctp->acmd + ccb->csio.cdb_len, 32 - ccb->csio.cdb_len); in fsl_sata_setup_fis()
1666 } else if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) { in fsl_sata_setup_fis()
1667 fis[1] |= 0x80; in fsl_sata_setup_fis()
1668 fis[2] = ccb->ataio.cmd.command; in fsl_sata_setup_fis()
1669 fis[3] = ccb->ataio.cmd.features; in fsl_sata_setup_fis()
1670 fis[4] = ccb->ataio.cmd.lba_low; in fsl_sata_setup_fis()
1671 fis[5] = ccb->ataio.cmd.lba_mid; in fsl_sata_setup_fis()
1672 fis[6] = ccb->ataio.cmd.lba_high; in fsl_sata_setup_fis()
1673 fis[7] = ccb->ataio.cmd.device; in fsl_sata_setup_fis()
1674 fis[8] = ccb->ataio.cmd.lba_low_exp; in fsl_sata_setup_fis()
1675 fis[9] = ccb->ataio.cmd.lba_mid_exp; in fsl_sata_setup_fis()
1676 fis[10] = ccb->ataio.cmd.lba_high_exp; in fsl_sata_setup_fis()
1677 fis[11] = ccb->ataio.cmd.features_exp; in fsl_sata_setup_fis()
1678 if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) { in fsl_sata_setup_fis()
1679 fis[12] = tag << 3; in fsl_sata_setup_fis()
1680 fis[13] = 0; in fsl_sata_setup_fis()
1682 fis[12] = ccb->ataio.cmd.sector_count; in fsl_sata_setup_fis()
1683 fis[13] = ccb->ataio.cmd.sector_count_exp; in fsl_sata_setup_fis()
1685 fis[15] = ATA_A_4BIT; in fsl_sata_setup_fis()
1687 fis[15] = ccb->ataio.cmd.control; in fsl_sata_setup_fis()
1696 if (ccb->ccb_h.target_id > 15) { in fsl_sata_check_ids()
1697 ccb->ccb_h.status = CAM_TID_INVALID; in fsl_sata_check_ids()
1699 return (-1); in fsl_sata_check_ids()
1701 if (ccb->ccb_h.target_lun != 0) { in fsl_sata_check_ids()
1702 ccb->ccb_h.status = CAM_LUN_INVALID; in fsl_sata_check_ids()
1704 return (-1); in fsl_sata_check_ids()
1714 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, in fsl_sataaction()
1715 ("fsl_sataaction func_code=0x%x\n", ccb->ccb_h.func_code)); in fsl_sataaction()
1718 switch (ccb->ccb_h.func_code) { in fsl_sataaction()
1724 if (ch->devices == 0 || in fsl_sataaction()
1725 (ch->pm_present == 0 && in fsl_sataaction()
1726 ccb->ccb_h.target_id > 0 && ccb->ccb_h.target_id < 15)) { in fsl_sataaction()
1727 ccb->ccb_h.status = CAM_SEL_TIMEOUT; in fsl_sataaction()
1730 ccb->ccb_h.recovery_type = RECOVERY_NONE; in fsl_sataaction()
1734 ch->frozen = ccb; in fsl_sataaction()
1736 xpt_freeze_simq(ch->sim, 1); in fsl_sataaction()
1743 ccb->ccb_h.status = CAM_REQ_INVALID; in fsl_sataaction()
1747 struct ccb_trans_settings *cts = &ccb->cts; in fsl_sataaction()
1752 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) in fsl_sataaction()
1753 d = &ch->curr[ccb->ccb_h.target_id]; in fsl_sataaction()
1755 d = &ch->user[ccb->ccb_h.target_id]; in fsl_sataaction()
1756 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION) in fsl_sataaction()
1757 d->revision = cts->xport_specific.sata.revision; in fsl_sataaction()
1758 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE) in fsl_sataaction()
1759 d->mode = cts->xport_specific.sata.mode; in fsl_sataaction()
1760 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) in fsl_sataaction()
1761 d->bytecount = min(8192, cts->xport_specific.sata.bytecount); in fsl_sataaction()
1762 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS) in fsl_sataaction()
1763 d->tags = min(FSL_SATA_MAX_SLOTS, cts->xport_specific.sata.tags); in fsl_sataaction()
1764 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM) in fsl_sataaction()
1765 ch->pm_present = cts->xport_specific.sata.pm_present; in fsl_sataaction()
1766 if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI) in fsl_sataaction()
1767 d->atapi = cts->xport_specific.sata.atapi; in fsl_sataaction()
1768 ccb->ccb_h.status = CAM_REQ_CMP; in fsl_sataaction()
1774 struct ccb_trans_settings *cts = &ccb->cts; in fsl_sataaction()
1780 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) in fsl_sataaction()
1781 d = &ch->curr[ccb->ccb_h.target_id]; in fsl_sataaction()
1783 d = &ch->user[ccb->ccb_h.target_id]; in fsl_sataaction()
1784 cts->protocol = PROTO_UNSPECIFIED; in fsl_sataaction()
1785 cts->protocol_version = PROTO_VERSION_UNSPECIFIED; in fsl_sataaction()
1786 cts->transport = XPORT_SATA; in fsl_sataaction()
1787 cts->transport_version = XPORT_VERSION_UNSPECIFIED; in fsl_sataaction()
1788 cts->proto_specific.valid = 0; in fsl_sataaction()
1789 cts->xport_specific.sata.valid = 0; in fsl_sataaction()
1790 if (cts->type == CTS_TYPE_CURRENT_SETTINGS && in fsl_sataaction()
1791 (ccb->ccb_h.target_id == 15 || in fsl_sataaction()
1792 (ccb->ccb_h.target_id == 0 && !ch->pm_present))) { in fsl_sataaction()
1793 status = ATA_INL(ch->r_mem, FSL_SATA_P_SSTS) & ATA_SS_SPD_MASK; in fsl_sataaction()
1795 cts->xport_specific.sata.revision = in fsl_sataaction()
1797 cts->xport_specific.sata.valid |= in fsl_sataaction()
1800 cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D; in fsl_sataaction()
1801 if (ch->pm_level) { in fsl_sataaction()
1802 cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ; in fsl_sataaction()
1804 cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN; in fsl_sataaction()
1805 cts->xport_specific.sata.caps &= in fsl_sataaction()
1806 ch->user[ccb->ccb_h.target_id].caps; in fsl_sataaction()
1807 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; in fsl_sataaction()
1809 cts->xport_specific.sata.revision = d->revision; in fsl_sataaction()
1810 cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION; in fsl_sataaction()
1811 cts->xport_specific.sata.caps = d->caps; in fsl_sataaction()
1812 cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS; in fsl_sataaction()
1814 cts->xport_specific.sata.mode = d->mode; in fsl_sataaction()
1815 cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE; in fsl_sataaction()
1816 cts->xport_specific.sata.bytecount = d->bytecount; in fsl_sataaction()
1817 cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT; in fsl_sataaction()
1818 cts->xport_specific.sata.pm_present = ch->pm_present; in fsl_sataaction()
1819 cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM; in fsl_sataaction()
1820 cts->xport_specific.sata.tags = d->tags; in fsl_sataaction()
1821 cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS; in fsl_sataaction()
1822 cts->xport_specific.sata.atapi = d->atapi; in fsl_sataaction()
1823 cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI; in fsl_sataaction()
1824 ccb->ccb_h.status = CAM_REQ_CMP; in fsl_sataaction()
1830 ccb->ccb_h.status = CAM_REQ_CMP; in fsl_sataaction()
1834 ccb->ccb_h.status = CAM_REQ_INVALID; in fsl_sataaction()
1838 struct ccb_pathinq *cpi = &ccb->cpi; in fsl_sataaction()
1840 cpi->version_num = 1; /* XXX??? */ in fsl_sataaction()
1841 cpi->hba_inquiry = PI_SDTR_ABLE; in fsl_sataaction()
1842 cpi->hba_inquiry |= PI_TAG_ABLE; in fsl_sataaction()
1848 cpi->hba_inquiry |= PI_SATAPM; in fsl_sataaction()
1850 cpi->target_sprt = 0; in fsl_sataaction()
1851 cpi->hba_misc = PIM_SEQSCAN | PIM_UNMAPPED; in fsl_sataaction()
1852 cpi->hba_eng_cnt = 0; in fsl_sataaction()
1857 cpi->max_target = 0; in fsl_sataaction()
1858 cpi->max_lun = 0; in fsl_sataaction()
1859 cpi->initiator_id = 0; in fsl_sataaction()
1860 cpi->bus_id = cam_sim_bus(sim); in fsl_sataaction()
1861 cpi->base_transfer_speed = 150000; in fsl_sataaction()
1862 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); in fsl_sataaction()
1863 strncpy(cpi->hba_vid, "FSL SATA", HBA_IDLEN); in fsl_sataaction()
1864 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); in fsl_sataaction()
1865 cpi->unit_number = cam_sim_unit(sim); in fsl_sataaction()
1866 cpi->transport = XPORT_SATA; in fsl_sataaction()
1867 cpi->transport_version = XPORT_VERSION_UNSPECIFIED; in fsl_sataaction()
1868 cpi->protocol = PROTO_ATA; in fsl_sataaction()
1869 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED; in fsl_sataaction()
1870 cpi->maxio = (FSL_SATA_SG_ENTRIES - 1) * PAGE_SIZE; in fsl_sataaction()
1871 cpi->ccb_h.status = CAM_REQ_CMP; in fsl_sataaction()
1875 ccb->ccb_h.status = CAM_REQ_INVALID; in fsl_sataaction()
1888 istatus = ATA_INL(ch->r_mem, FSL_SATA_P_HSTS); in fsl_satapoll()