Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/ahci/ahci.c
Show First 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | resource_int_value(device_get_name(dev), | ||||
device_get_unit(dev), "ccc", &ctlr->ccc); | device_get_unit(dev), "ccc", &ctlr->ccc); | ||||
/* Setup our own memory management for channels. */ | /* Setup our own memory management for channels. */ | ||||
ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem); | ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem); | ||||
ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem); | ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem); | ||||
ctlr->sc_iomem.rm_type = RMAN_ARRAY; | ctlr->sc_iomem.rm_type = RMAN_ARRAY; | ||||
ctlr->sc_iomem.rm_descr = "I/O memory addresses"; | ctlr->sc_iomem.rm_descr = "I/O memory addresses"; | ||||
if ((error = rman_init(&ctlr->sc_iomem)) != 0) { | if ((error = rman_init(&ctlr->sc_iomem)) != 0) { | ||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); | ahci_free_mem(dev); | ||||
return (error); | return (error); | ||||
} | } | ||||
if ((error = rman_manage_region(&ctlr->sc_iomem, | if ((error = rman_manage_region(&ctlr->sc_iomem, | ||||
rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) { | rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) { | ||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); | ahci_free_mem(dev); | ||||
rman_fini(&ctlr->sc_iomem); | rman_fini(&ctlr->sc_iomem); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* Get the HW capabilities */ | /* Get the HW capabilities */ | ||||
version = ATA_INL(ctlr->r_mem, AHCI_VS); | version = ATA_INL(ctlr->r_mem, AHCI_VS); | ||||
ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP); | ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP); | ||||
if (version >= 0x00010200) | if (version >= 0x00010200) | ||||
ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2); | ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | ahci_attach(device_t dev) | ||||
ctlr->emloc = ATA_INL(ctlr->r_mem, AHCI_EM_LOC); | ctlr->emloc = ATA_INL(ctlr->r_mem, AHCI_EM_LOC); | ||||
/* Create controller-wide DMA tag. */ | /* Create controller-wide DMA tag. */ | ||||
if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, | if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, | ||||
(ctlr->caps & AHCI_CAP_64BIT) ? BUS_SPACE_MAXADDR : | (ctlr->caps & AHCI_CAP_64BIT) ? BUS_SPACE_MAXADDR : | ||||
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
BUS_SPACE_MAXSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE, | BUS_SPACE_MAXSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE, | ||||
0, NULL, NULL, &ctlr->dma_tag)) { | 0, NULL, NULL, &ctlr->dma_tag)) { | ||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, | ahci_free_mem(dev); | ||||
ctlr->r_mem); | |||||
rman_fini(&ctlr->sc_iomem); | rman_fini(&ctlr->sc_iomem); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
ahci_ctlr_setup(dev); | ahci_ctlr_setup(dev); | ||||
/* Setup interrupts. */ | /* Setup interrupts. */ | ||||
if ((error = ahci_setup_interrupt(dev)) != 0) { | if ((error = ahci_setup_interrupt(dev)) != 0) { | ||||
bus_dma_tag_destroy(ctlr->dma_tag); | bus_dma_tag_destroy(ctlr->dma_tag); | ||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, | ahci_free_mem(dev); | ||||
ctlr->r_mem); | |||||
rman_fini(&ctlr->sc_iomem); | rman_fini(&ctlr->sc_iomem); | ||||
return (error); | return (error); | ||||
} | } | ||||
i = 0; | i = 0; | ||||
for (u = ctlr->ichannels; u != 0; u >>= 1) | for (u = ctlr->ichannels; u != 0; u >>= 1) | ||||
i += (u & 1); | i += (u & 1); | ||||
ctlr->direct = (ctlr->msi && (ctlr->numirqs > 1 || i <= 3)); | ctlr->direct = (ctlr->msi && (ctlr->numirqs > 1 || i <= 3)); | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (ctlr->irqs[i].r_irq) { | ||||
ctlr->irqs[i].handle); | ctlr->irqs[i].handle); | ||||
bus_release_resource(dev, SYS_RES_IRQ, | bus_release_resource(dev, SYS_RES_IRQ, | ||||
ctlr->irqs[i].r_irq_rid, ctlr->irqs[i].r_irq); | ctlr->irqs[i].r_irq_rid, ctlr->irqs[i].r_irq); | ||||
} | } | ||||
} | } | ||||
bus_dma_tag_destroy(ctlr->dma_tag); | bus_dma_tag_destroy(ctlr->dma_tag); | ||||
/* Free memory. */ | /* Free memory. */ | ||||
rman_fini(&ctlr->sc_iomem); | rman_fini(&ctlr->sc_iomem); | ||||
ahci_free_mem(dev); | |||||
return (0); | |||||
} | |||||
void | |||||
ahci_free_mem(device_t dev) | |||||
{ | |||||
struct ahci_controller *ctlr = device_get_softc(dev); | |||||
/* Release memory resources */ | |||||
if (ctlr->r_mem) | if (ctlr->r_mem) | ||||
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); | bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); | ||||
return (0); | if (ctlr->r_msix_table) | ||||
bus_release_resource(dev, SYS_RES_MEMORY, | |||||
ctlr->r_msix_tab_rid, ctlr->r_msix_table); | |||||
if (ctlr->r_msix_pba) | |||||
bus_release_resource(dev, SYS_RES_MEMORY, | |||||
ctlr->r_msix_pba_rid, ctlr->r_msix_pba); | |||||
ctlr->r_msix_pba = ctlr->r_mem = ctlr->r_msix_table = NULL; | |||||
} | } | ||||
int | int | ||||
ahci_setup_interrupt(device_t dev) | ahci_setup_interrupt(device_t dev) | ||||
{ | { | ||||
struct ahci_controller *ctlr = device_get_softc(dev); | struct ahci_controller *ctlr = device_get_softc(dev); | ||||
int i; | int i; | ||||
▲ Show 20 Lines • Show All 2,327 Lines • Show Last 20 Lines |