Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/pseries/phyp_llan.c
Show First 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | llan_probe(device_t dev) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
llan_attach(device_t dev) | llan_attach(device_t dev) | ||||
{ | { | ||||
struct llan_softc *sc; | struct llan_softc *sc; | ||||
phandle_t node; | phandle_t node; | ||||
int error, i; | int error, i; | ||||
jhibbits: I think this is incorrect, and error should be handled. | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->dev = dev; | sc->dev = dev; | ||||
/* Get firmware properties */ | /* Get firmware properties */ | ||||
node = ofw_bus_get_node(dev); | node = ofw_bus_get_node(dev); | ||||
OF_getprop(node, "local-mac-address", sc->mac_address, | OF_getprop(node, "local-mac-address", sc->mac_address, | ||||
sizeof(sc->mac_address)); | sizeof(sc->mac_address)); | ||||
Show All 11 Lines | if (!sc->irq) { | ||||
mtx_destroy(&sc->io_lock); | mtx_destroy(&sc->io_lock); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE | | bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE | | ||||
INTR_ENTROPY, NULL, llan_intr, sc, &sc->irq_cookie); | INTR_ENTROPY, NULL, llan_intr, sc, &sc->irq_cookie); | ||||
/* Setup DMA */ | /* Setup DMA */ | ||||
error = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0, | error = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0, | ||||
Not Done Inline ActionsDon't ignore it, handle it. jhibbits: Don't ignore it, handle it. | |||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
LLAN_RX_BUF_LEN, 1, BUS_SPACE_MAXSIZE_32BIT, | LLAN_RX_BUF_LEN, 1, BUS_SPACE_MAXSIZE_32BIT, | ||||
0, NULL, NULL, &sc->rx_dma_tag); | 0, NULL, NULL, &sc->rx_dma_tag); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not create rx_dma_tag DMA tag\n"); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
jhibbitsUnsubmitted Not Done Inline ActionsYou need to clean up the resource allocations when you exit prematurely. Often there'll be a label at the end of the function to do cleanup before returning error. jhibbits: You need to clean up the resource allocations when you exit prematurely. Often there'll be a… | |||||
} | |||||
error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0, | error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0, | ||||
BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
BUS_SPACE_MAXSIZE, 1, BUS_SPACE_MAXSIZE_32BIT, | BUS_SPACE_MAXSIZE, 1, BUS_SPACE_MAXSIZE_32BIT, | ||||
0, NULL, NULL, &sc->rxbuf_dma_tag); | 0, NULL, NULL, &sc->rxbuf_dma_tag); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not create rxbuf_dma_tag DMA tag\n"); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
} | |||||
error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, | error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, | ||||
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, | BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, | ||||
BUS_SPACE_MAXSIZE, 6, BUS_SPACE_MAXSIZE_32BIT, 0, | BUS_SPACE_MAXSIZE, 6, BUS_SPACE_MAXSIZE_32BIT, 0, | ||||
busdma_lock_mutex, &sc->io_lock, &sc->tx_dma_tag); | busdma_lock_mutex, &sc->io_lock, &sc->tx_dma_tag); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not create tx_dma_tag DMA tag\n"); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
} | |||||
error = bus_dmamem_alloc(sc->rx_dma_tag, (void **)&sc->rx_buf, | error = bus_dmamem_alloc(sc->rx_dma_tag, (void **)&sc->rx_buf, | ||||
BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx_buf_map); | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx_buf_map); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not allocate rx_buf_map area\n"); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
} | |||||
error = bus_dmamap_load(sc->rx_dma_tag, sc->rx_buf_map, sc->rx_buf, | error = bus_dmamap_load(sc->rx_dma_tag, sc->rx_buf_map, sc->rx_buf, | ||||
LLAN_RX_BUF_LEN, llan_rx_load_cb, sc, 0); | LLAN_RX_BUF_LEN, llan_rx_load_cb, sc, 0); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not DMA map llna_rx_load_cb\n"); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
} | |||||
/* TX DMA maps */ | /* TX DMA maps */ | ||||
bus_dmamap_create(sc->tx_dma_tag, 0, &sc->tx_dma_map); | bus_dmamap_create(sc->tx_dma_tag, 0, &sc->tx_dma_map); | ||||
/* RX DMA */ | /* RX DMA */ | ||||
for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) { | for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) { | ||||
error = bus_dmamap_create(sc->rxbuf_dma_tag, 0, | error = bus_dmamap_create(sc->rxbuf_dma_tag, 0, | ||||
&sc->rx_xfer[i].rx_dmamap); | &sc->rx_xfer[i].rx_dmamap); | ||||
if (error != 0) { | |||||
device_printf(dev, "Could not allocate DMA map for packet %d\n", i); | |||||
mtx_destroy(&sc->io_lock); | |||||
return (ENXIO); | |||||
} | |||||
sc->rx_xfer[i].rx_mbuf = NULL; | sc->rx_xfer[i].rx_mbuf = NULL; | ||||
} | } | ||||
/* Attach to network stack */ | /* Attach to network stack */ | ||||
sc->ifp = if_alloc(IFT_ETHER); | sc->ifp = if_alloc(IFT_ETHER); | ||||
sc->ifp->if_softc = sc; | sc->ifp->if_softc = sc; | ||||
if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); | if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void | static void | ||||
llan_init(void *xsc) | llan_init(void *xsc) | ||||
{ | { | ||||
struct llan_softc *sc = xsc; | struct llan_softc *sc = xsc; | ||||
uint64_t rx_buf_desc; | uint64_t rx_buf_desc; | ||||
uint64_t macaddr; | uint64_t macaddr; | ||||
int err, i; | int err, i; | ||||
Not Done Inline ActionsError should be handled, not ignored. jhibbits: Error should be handled, not ignored. | |||||
mtx_lock(&sc->io_lock); | mtx_lock(&sc->io_lock); | ||||
phyp_hcall(H_FREE_LOGICAL_LAN, sc->unit); | phyp_hcall(H_FREE_LOGICAL_LAN, sc->unit); | ||||
/* Create buffers (page 539) */ | /* Create buffers (page 539) */ | ||||
sc->rx_dma_slot = 0; | sc->rx_dma_slot = 0; | ||||
sc->rx_valid_val = 1; | sc->rx_valid_val = 1; | ||||
rx_buf_desc = LLAN_BUFDESC_VALID; | rx_buf_desc = LLAN_BUFDESC_VALID; | ||||
rx_buf_desc |= (sc->rx_buf_len << 32); | rx_buf_desc |= (sc->rx_buf_len << 32); | ||||
rx_buf_desc |= sc->rx_buf_phys; | rx_buf_desc |= sc->rx_buf_phys; | ||||
memcpy(&macaddr, sc->mac_address, 8); | memcpy(&macaddr, sc->mac_address, 8); | ||||
err = phyp_hcall(H_REGISTER_LOGICAL_LAN, sc->unit, sc->input_buf_phys, | err = phyp_hcall(H_REGISTER_LOGICAL_LAN, sc->unit, sc->input_buf_phys, | ||||
rx_buf_desc, sc->filter_buf_phys, macaddr); | rx_buf_desc, sc->filter_buf_phys, macaddr); | ||||
if (err != 0){ | |||||
device_printf(sc->dev, "Unable to register llan"); | |||||
mtx_unlock(&sc->io_lock); | |||||
return; | |||||
jhibbitsUnsubmitted Not Done Inline ActionsIs there any cleanup needed from the H_FREE_LOGICAL_LAN call if this second hcall fails? jhibbits: Is there any cleanup needed from the H_FREE_LOGICAL_LAN call if this second hcall fails? | |||||
} | |||||
for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) | for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) | ||||
llan_add_rxbuf(sc, &sc->rx_xfer[i]); | llan_add_rxbuf(sc, &sc->rx_xfer[i]); | ||||
phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */ | phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */ | ||||
/* Tell stack we're up */ | /* Tell stack we're up */ | ||||
sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; | sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; | ||||
▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | llan_send_packet(void *xsc, bus_dma_segment_t *segs, int nsegs, | ||||
* the packet in such cases. | * the packet in such cases. | ||||
*/ | */ | ||||
} | } | ||||
static void | static void | ||||
llan_start_locked(struct ifnet *ifp) | llan_start_locked(struct ifnet *ifp) | ||||
{ | { | ||||
struct llan_softc *sc = ifp->if_softc; | struct llan_softc *sc = ifp->if_softc; | ||||
bus_addr_t first; | |||||
int nsegs; | int nsegs; | ||||
struct mbuf *mb_head, *m; | struct mbuf *mb_head, *m; | ||||
mtx_assert(&sc->io_lock, MA_OWNED); | mtx_assert(&sc->io_lock, MA_OWNED); | ||||
first = 0; | |||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != | if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != | ||||
IFF_DRV_RUNNING) | IFF_DRV_RUNNING) | ||||
return; | return; | ||||
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { | while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { | ||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, mb_head); | IFQ_DRV_DEQUEUE(&ifp->if_snd, mb_head); | ||||
▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines |
I think this is incorrect, and error should be handled.