| 209 | } |
| 210 | |
| 211 | static int |
| 212 | ccp_hw_attach_queue(device_t dev, uint64_t lsbmask, unsigned queue) |
| 213 | { |
| 214 | struct ccp_softc *sc; |
| 215 | struct ccp_queue *qp; |
| 216 | void *desc; |
| 217 | size_t ringsz, num_descriptors; |
| 218 | int error; |
| 219 | |
| 220 | desc = NULL; |
| 221 | sc = device_get_softc(dev); |
| 222 | qp = &sc->queues[queue]; |
| 223 | |
| 224 | /* |
| 225 | * Don't bother allocating a ring for queues the host isn't allowed to |
| 226 | * drive. |
| 227 | */ |
| 228 | if ((sc->valid_queues & (1 << queue)) == 0) |
| 229 | return (0); |
| 230 | |
| 231 | ccp_queue_decode_lsb_regions(sc, lsbmask, queue); |
| 232 | |
| 233 | /* Ignore queues that do not have any LSB access. */ |
| 234 | if (qp->lsb_mask == 0) { |
| 235 | device_printf(dev, "Ignoring queue %u with no LSB access\n", |
| 236 | queue); |
| 237 | sc->valid_queues &= ~(1 << queue); |
| 238 | return (0); |
| 239 | } |
| 240 | |
| 241 | num_descriptors = 1 << sc->ring_size_order; |
| 242 | ringsz = sizeof(struct ccp_desc) * num_descriptors; |
| 243 | |
| 244 | /* |
| 245 | * "Queue_Size" is order - 1. |
| 246 | * |
| 247 | * Queue must be aligned to 5+Queue_Size+1 == 5 + order bits. |
| 248 | */ |
| 249 | error = bus_dma_tag_create(bus_get_dma_tag(dev), |
| 250 | 1 << (5 + sc->ring_size_order), |
| 251 | #if defined(__i386__) && !defined(PAE) |
| 252 | 0, BUS_SPACE_MAXADDR, |
| 253 | #else |
| 254 | (bus_addr_t)1 << 32, BUS_SPACE_MAXADDR_48BIT, |
| 255 | #endif |
| 256 | BUS_SPACE_MAXADDR, NULL, NULL, ringsz, 1, |
| 257 | ringsz, 0, NULL, NULL, &qp->ring_desc_tag); |
| 258 | if (error != 0) |
| 259 | goto out; |
| 260 | |
| 261 | error = bus_dmamem_alloc(qp->ring_desc_tag, &desc, |
| 262 | BUS_DMA_ZERO | BUS_DMA_WAITOK, &qp->ring_desc_map); |
| 263 | if (error != 0) |
| 264 | goto out; |
| 265 | |
| 266 | error = bus_dmamap_load(qp->ring_desc_tag, qp->ring_desc_map, desc, |
| 267 | ringsz, ccp_dmamap_cb, &qp->desc_ring_bus_addr, BUS_DMA_WAITOK); |
| 268 | if (error != 0) |
no test coverage detected