Lines Matching full:ch

65 static void fsl_sata_intr_main(struct fsl_sata_channel *ch, uint32_t istatus);
66 static void fsl_sata_begin_transaction(struct fsl_sata_channel *ch, union ccb *ccb);
71 static int fsl_sata_setup_fis(struct fsl_sata_channel *ch, struct fsl_sata_cmd_tab *ctp, union ccb …
77 static void fsl_sata_reset(struct fsl_sata_channel *ch);
78 static void fsl_sata_start(struct fsl_sata_channel *ch);
79 static void fsl_sata_stop(struct fsl_sata_channel *ch);
81 static void fsl_sata_issue_recovery(struct fsl_sata_channel *ch);
82 static void fsl_sata_process_read_log(struct fsl_sata_channel *ch, union ccb *ccb);
83 static void fsl_sata_process_request_sense(struct fsl_sata_channel *ch, union ccb *ccb);
157 #define FSL_SATA_CTP_BUS(ch, slot) \ argument
158 ((ch->dma.work_bus + FSL_SATA_CT_OFFSET + (FSL_SATA_CT_SIZE * slot->slot)))
160 #define FSL_SATA_CTP(ch, slot) \ argument
161 ((struct fsl_sata_cmd_tab *)(ch->dma.work + FSL_SATA_CT_OFFSET + \
163 #define FSL_SATA_CLP(ch, slot) \ argument
164 ((struct fsl_sata_cmd_list *) (ch->dma.work + FSL_SATA_CL_OFFSET + \
231 struct fsl_sata_channel *ch; /* Channel */ member
326 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_attach() local
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()
405 fsl_sata_pm, ch); 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()
426 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_detach() local
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()
451 fsl_sata_wait_register(struct fsl_sata_channel *ch, bus_size_t off, in fsl_sata_wait_register() argument
457 while (((rval = ATA_INL(ch->r_mem, off)) & mask) != val) { in fsl_sata_wait_register()
470 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_init() local
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()
479 fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, 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()
490 fsl_sata_start(ch); in fsl_sata_init()
497 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_deinit() local
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()
504 fsl_sata_stop(ch); 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()
519 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_suspend() local
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()
533 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_resume() local
535 mtx_lock(&ch->mtx); in fsl_sata_resume()
537 fsl_sata_reset(ch); in fsl_sata_resume()
538 xpt_release_simq(ch->sim, TRUE); in fsl_sata_resume()
539 mtx_unlock(&ch->mtx); in fsl_sata_resume()
568 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_dmainit() local
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()
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()
615 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_dmafini() local
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()
636 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_slotsalloc() local
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()
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()
658 struct fsl_sata_channel *ch = device_get_softc(dev); in fsl_sata_slotsfree() local
663 struct fsl_sata_slot *slot = &ch->slot[i]; in fsl_sata_slotsfree()
667 bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map); in fsl_sata_slotsfree()
674 fsl_sata_phy_check_events(struct fsl_sata_channel *ch, u_int32_t serr) in fsl_sata_phy_check_events() argument
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()
693 cam_sim_path(ch->sim), in fsl_sata_phy_check_events()
705 fsl_sata_notify_events(struct fsl_sata_channel *ch, u_int32_t status) in fsl_sata_notify_events() argument
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()
725 fsl_sata_done(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_done() argument
728 mtx_assert(&ch->mtx, MA_OWNED); 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()
741 struct fsl_sata_channel *ch = (struct fsl_sata_channel *)arg; in fsl_sata_intr() local
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()
753 fsl_sata_intr_main(ch, istatus); 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()
773 struct fsl_sata_channel *ch = (struct fsl_sata_channel *)arg; in fsl_sata_pm() local
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()
788 fsl_sata_intr_main(struct fsl_sata_channel *ch, uint32_t istatus) in fsl_sata_intr_main() argument
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()
813 fsl_sata_phy_check_events(ch, 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()
832 fsl_sata_done(ch, fccb); 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()
848 fsl_sata_notify_events(ch, sntf); in fsl_sata_intr_main()
853 fsl_sata_check_collision(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_check_collision() argument
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()
873 if (ch->numrslots != 0) in fsl_sata_check_collision()
877 if (ch->aslots != 0) in fsl_sata_check_collision()
884 fsl_sata_begin_transaction(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_begin_transaction() argument
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()
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()
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()
924 ch->aslots |= (1 << tag); in fsl_sata_begin_transaction()
927 bus_dmamap_load_ccb(ch->dma.data_tag, slot->dma.data_map, ccb, in fsl_sata_begin_transaction()
943 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_dmasetprd() local
949 device_printf(ch->dev, "DMA load error %d\n", error); in fsl_sata_dmasetprd()
956 ctp = FSL_SATA_CTP(ch, slot); in fsl_sata_dmasetprd()
962 prd[j].dba = htole32(FSL_SATA_CTP_BUS(ch, slot) + in fsl_sata_dmasetprd()
979 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, in fsl_sata_dmasetprd()
989 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_execute_transaction() local
1002 ctp = FSL_SATA_CTP(ch, slot); 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()
1010 clp = FSL_SATA_CLP(ch, slot); 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()
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()
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()
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()
1087 fsl_sata_process_timeout(struct fsl_sata_channel *ch) in fsl_sata_process_timeout() argument
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()
1103 fsl_sata_rearm_timeout(struct fsl_sata_channel *ch) in fsl_sata_rearm_timeout() argument
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()
1114 if ((ch->toslots & (1 << i)) == 0) in fsl_sata_rearm_timeout()
1127 struct fsl_sata_channel *ch = slot->ch; in fsl_sata_timeout() local
1128 device_t dev = ch->dev; in fsl_sata_timeout()
1138 sstatus = ATA_INL(ch->r_mem, FSL_SATA_P_CAR); 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()
1160 fsl_sata_done(ch, fccb); 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()
1166 fsl_sata_process_timeout(ch); 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() local
1182 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, in fsl_sata_end_transaction()
1184 clp = FSL_SATA_CLP(ch, slot); in fsl_sata_end_transaction()
1191 struct fsl_sata_cmd_tab *ctp = FSL_SATA_CTP(ch, slot); in fsl_sata_end_transaction()
1208 sig = ATA_INL(ch->r_mem, FSL_SATA_P_SIG); in fsl_sata_end_transaction()
1228 bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map, 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()
1250 ch->fatalerr = 1; 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()
1275 if (!ch->recoverycmd) { in fsl_sata_end_transaction()
1276 xpt_freeze_simq(ch->sim, 1); in fsl_sata_end_transaction()
1283 ch->fatalerr = 1; 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()
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()
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()
1315 fsl_sata_begin_transaction(ch, ccb); in fsl_sata_end_transaction()
1320 fsl_sata_process_read_log(ch, ccb); in fsl_sata_end_transaction()
1323 fsl_sata_process_request_sense(ch, ccb); in fsl_sata_end_transaction()
1328 ch->hold[slot->slot] = ccb; in fsl_sata_end_transaction()
1329 ch->numhslots++; in fsl_sata_end_transaction()
1331 fsl_sata_done(ch, ccb); in fsl_sata_end_transaction()
1333 if (ch->rslots == 0) { in fsl_sata_end_transaction()
1335 if (ch->toslots != 0 || ch->fatalerr) { in fsl_sata_end_transaction()
1336 fsl_sata_reset(ch); in fsl_sata_end_transaction()
1339 if (ch->eslots != 0) { in fsl_sata_end_transaction()
1340 fsl_sata_stop(ch); in fsl_sata_end_transaction()
1341 fsl_sata_start(ch); in fsl_sata_end_transaction()
1344 if (!ch->recoverycmd && ch->numhslots) in fsl_sata_end_transaction()
1345 fsl_sata_issue_recovery(ch); in fsl_sata_end_transaction()
1348 } else if ((ch->rslots & ~ch->toslots) == 0 && in fsl_sata_end_transaction()
1350 fsl_sata_rearm_timeout(ch); 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()
1355 fsl_sata_begin_transaction(ch, fccb); 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()
1367 fsl_sata_issue_recovery(struct fsl_sata_channel *ch) in fsl_sata_issue_recovery() argument
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()
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()
1393 fsl_sata_reset(ch); in fsl_sata_issue_recovery()
1396 ccb->ccb_h = ch->hold[i]->ccb_h; /* Reuse old header. */ in fsl_sata_issue_recovery()
1407 device_printf(ch->dev, 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()
1437 ch->recoverycmd = 1; in fsl_sata_issue_recovery()
1438 xpt_freeze_simq(ch->sim, 1); in fsl_sata_issue_recovery()
1439 fsl_sata_begin_transaction(ch, ccb); in fsl_sata_issue_recovery()
1443 fsl_sata_process_read_log(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_process_read_log() argument
1449 ch->recoverycmd = 0; 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()
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()
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()
1498 xpt_release_simq(ch->sim, TRUE); in fsl_sata_process_read_log()
1502 fsl_sata_process_request_sense(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_process_request_sense() argument
1506 ch->recoverycmd = 0; 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()
1523 fsl_sata_start(struct fsl_sata_channel *ch) in fsl_sata_start() argument
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()
1539 fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, 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()
1546 fsl_sata_stop(struct fsl_sata_channel *ch) in fsl_sata_stop() argument
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()
1557 if (fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, in fsl_sata_stop()
1560 device_printf(ch->dev, in fsl_sata_stop()
1566 ch->eslots = 0; in fsl_sata_stop()
1570 fsl_sata_reset(struct fsl_sata_channel *ch) in fsl_sata_reset() argument
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()
1588 fsl_sata_done(ch, fccb); in fsl_sata_reset()
1591 fsl_sata_stop(ch); 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()
1618 fsl_sata_start(ch); in fsl_sata_reset()
1619 if (fsl_sata_wait_register(ch, FSL_SATA_P_HSTS, 0x08, 0x08, 500)) { 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()
1643 fsl_sata_setup_fis(struct fsl_sata_channel *ch, struct fsl_sata_cmd_tab *ctp, union ccb *ccb, int t… in fsl_sata_setup_fis() argument
1654 ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA) in fsl_sata_setup_fis()
1693 fsl_sata_check_ids(struct fsl_sata_channel *ch, union ccb *ccb) in fsl_sata_check_ids() argument
1698 fsl_sata_done(ch, ccb); in fsl_sata_check_ids()
1703 fsl_sata_done(ch, ccb); in fsl_sata_check_ids()
1712 struct fsl_sata_channel *ch; in fsl_sataaction() local
1717 ch = (struct fsl_sata_channel *)cam_sim_softc(sim); in fsl_sataaction()
1722 if (fsl_sata_check_ids(ch, ccb)) in fsl_sataaction()
1724 if (ch->devices == 0 || in fsl_sataaction()
1725 (ch->pm_present == 0 && in fsl_sataaction()
1732 if (fsl_sata_check_collision(ch, ccb)) { in fsl_sataaction()
1734 ch->frozen = ccb; in fsl_sataaction()
1736 xpt_freeze_simq(ch->sim, 1); in fsl_sataaction()
1739 fsl_sata_begin_transaction(ch, ccb); in fsl_sataaction()
1750 if (fsl_sata_check_ids(ch, ccb)) 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()
1765 ch->pm_present = cts->xport_specific.sata.pm_present; in fsl_sataaction()
1778 if (fsl_sata_check_ids(ch, ccb)) 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()
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()
1801 if (ch->pm_level) { in fsl_sataaction()
1806 ch->user[ccb->ccb_h.target_id].caps; in fsl_sataaction()
1818 cts->xport_specific.sata.pm_present = ch->pm_present; in fsl_sataaction()
1829 fsl_sata_reset(ch); in fsl_sataaction()
1878 fsl_sata_done(ch, ccb); in fsl_sataaction()
1884 struct fsl_sata_channel *ch = (struct fsl_sata_channel *)cam_sim_softc(sim); in fsl_satapoll() local
1888 istatus = ATA_INL(ch->r_mem, FSL_SATA_P_HSTS); in fsl_satapoll()
1890 fsl_sata_intr_main(ch, istatus); in fsl_satapoll()