diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-04-27 22:57:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:49 -0400 |
commit | 3ffbba9511b4148cbe1f6b6238686adaeaca8feb (patch) | |
tree | f69e42d07d596039e049fe2b14b720ddc6be2694 /drivers/usb/host/xhci-mem.c | |
parent | c6515272b858742962c1de0f3bf497a048b9abd7 (diff) |
USB: xhci: Allocate and address USB devices
xHCI needs to get a "Slot ID" from the host controller and allocate other
data structures for every USB device. Make usb_alloc_dev() and
usb_release_dev() allocate and free these device structures. After
setting up the xHC device structures, usb_alloc_dev() must wait for the
hardware to respond to an Enable Slot command. usb_alloc_dev() fires off
a Disable Slot command and does not wait for it to complete.
When the USB core wants to choose an address for the device, the xHCI
driver must issue a Set Address command and wait for an event for that
command.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 204 |
1 files changed, 199 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 005d44641d81..d34b91a135a1 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -188,12 +188,187 @@ fail: | |||
188 | return 0; | 188 | return 0; |
189 | } | 189 | } |
190 | 190 | ||
191 | void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) | ||
192 | { | ||
193 | struct xhci_virt_device *dev; | ||
194 | int i; | ||
195 | |||
196 | /* Slot ID 0 is reserved */ | ||
197 | if (slot_id == 0 || !xhci->devs[slot_id]) | ||
198 | return; | ||
199 | |||
200 | dev = xhci->devs[slot_id]; | ||
201 | xhci->dcbaa->dev_context_ptrs[2*slot_id] = 0; | ||
202 | xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0; | ||
203 | if (!dev) | ||
204 | return; | ||
205 | |||
206 | for (i = 0; i < 31; ++i) | ||
207 | if (dev->ep_rings[i]) | ||
208 | xhci_ring_free(xhci, dev->ep_rings[i]); | ||
209 | |||
210 | if (dev->in_ctx) | ||
211 | dma_pool_free(xhci->device_pool, | ||
212 | dev->in_ctx, dev->in_ctx_dma); | ||
213 | if (dev->out_ctx) | ||
214 | dma_pool_free(xhci->device_pool, | ||
215 | dev->out_ctx, dev->out_ctx_dma); | ||
216 | kfree(xhci->devs[slot_id]); | ||
217 | xhci->devs[slot_id] = 0; | ||
218 | } | ||
219 | |||
220 | int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | ||
221 | struct usb_device *udev, gfp_t flags) | ||
222 | { | ||
223 | dma_addr_t dma; | ||
224 | struct xhci_virt_device *dev; | ||
225 | |||
226 | /* Slot ID 0 is reserved */ | ||
227 | if (slot_id == 0 || xhci->devs[slot_id]) { | ||
228 | xhci_warn(xhci, "Bad Slot ID %d\n", slot_id); | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | xhci->devs[slot_id] = kzalloc(sizeof(*xhci->devs[slot_id]), flags); | ||
233 | if (!xhci->devs[slot_id]) | ||
234 | return 0; | ||
235 | dev = xhci->devs[slot_id]; | ||
236 | |||
237 | /* Allocate the (output) device context that will be used in the HC */ | ||
238 | dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); | ||
239 | if (!dev->out_ctx) | ||
240 | goto fail; | ||
241 | dev->out_ctx_dma = dma; | ||
242 | xhci_dbg(xhci, "Slot %d output ctx = 0x%x (dma)\n", slot_id, dma); | ||
243 | memset(dev->out_ctx, 0, sizeof(*dev->out_ctx)); | ||
244 | |||
245 | /* Allocate the (input) device context for address device command */ | ||
246 | dev->in_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma); | ||
247 | if (!dev->in_ctx) | ||
248 | goto fail; | ||
249 | dev->in_ctx_dma = dma; | ||
250 | xhci_dbg(xhci, "Slot %d input ctx = 0x%x (dma)\n", slot_id, dma); | ||
251 | memset(dev->in_ctx, 0, sizeof(*dev->in_ctx)); | ||
252 | |||
253 | /* Allocate endpoint 0 ring */ | ||
254 | dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags); | ||
255 | if (!dev->ep_rings[0]) | ||
256 | goto fail; | ||
257 | |||
258 | /* | ||
259 | * Point to output device context in dcbaa; skip the output control | ||
260 | * context, which is eight 32 bit fields (or 32 bytes long) | ||
261 | */ | ||
262 | xhci->dcbaa->dev_context_ptrs[2*slot_id] = | ||
263 | (u32) dev->out_ctx_dma + (32); | ||
264 | xhci_dbg(xhci, "Set slot id %d dcbaa entry 0x%x to 0x%x\n", | ||
265 | slot_id, | ||
266 | (unsigned int) &xhci->dcbaa->dev_context_ptrs[2*slot_id], | ||
267 | dev->out_ctx_dma); | ||
268 | xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0; | ||
269 | |||
270 | return 1; | ||
271 | fail: | ||
272 | xhci_free_virt_device(xhci, slot_id); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | /* Setup an xHCI virtual device for a Set Address command */ | ||
277 | int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev) | ||
278 | { | ||
279 | struct xhci_virt_device *dev; | ||
280 | struct xhci_ep_ctx *ep0_ctx; | ||
281 | struct usb_device *top_dev; | ||
282 | |||
283 | dev = xhci->devs[udev->slot_id]; | ||
284 | /* Slot ID 0 is reserved */ | ||
285 | if (udev->slot_id == 0 || !dev) { | ||
286 | xhci_warn(xhci, "Slot ID %d is not assigned to this device\n", | ||
287 | udev->slot_id); | ||
288 | return -EINVAL; | ||
289 | } | ||
290 | ep0_ctx = &dev->in_ctx->ep[0]; | ||
291 | |||
292 | /* 2) New slot context and endpoint 0 context are valid*/ | ||
293 | dev->in_ctx->add_flags = SLOT_FLAG | EP0_FLAG; | ||
294 | |||
295 | /* 3) Only the control endpoint is valid - one endpoint context */ | ||
296 | dev->in_ctx->slot.dev_info |= LAST_CTX(1); | ||
297 | |||
298 | switch (udev->speed) { | ||
299 | case USB_SPEED_SUPER: | ||
300 | dev->in_ctx->slot.dev_info |= (u32) udev->route; | ||
301 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_SS; | ||
302 | break; | ||
303 | case USB_SPEED_HIGH: | ||
304 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_HS; | ||
305 | break; | ||
306 | case USB_SPEED_FULL: | ||
307 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_FS; | ||
308 | break; | ||
309 | case USB_SPEED_LOW: | ||
310 | dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_LS; | ||
311 | break; | ||
312 | case USB_SPEED_VARIABLE: | ||
313 | xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n"); | ||
314 | return -EINVAL; | ||
315 | break; | ||
316 | default: | ||
317 | /* Speed was set earlier, this shouldn't happen. */ | ||
318 | BUG(); | ||
319 | } | ||
320 | /* Find the root hub port this device is under */ | ||
321 | for (top_dev = udev; top_dev->parent && top_dev->parent->parent; | ||
322 | top_dev = top_dev->parent) | ||
323 | /* Found device below root hub */; | ||
324 | dev->in_ctx->slot.dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); | ||
325 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); | ||
326 | |||
327 | /* Is this a LS/FS device under a HS hub? */ | ||
328 | /* | ||
329 | * FIXME: I don't think this is right, where does the TT info for the | ||
330 | * roothub or parent hub come from? | ||
331 | */ | ||
332 | if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) && | ||
333 | udev->tt) { | ||
334 | dev->in_ctx->slot.tt_info = udev->tt->hub->slot_id; | ||
335 | dev->in_ctx->slot.tt_info |= udev->ttport << 8; | ||
336 | } | ||
337 | xhci_dbg(xhci, "udev->tt = 0x%x\n", (unsigned int) udev->tt); | ||
338 | xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport); | ||
339 | |||
340 | /* Step 4 - ring already allocated */ | ||
341 | /* Step 5 */ | ||
342 | ep0_ctx->ep_info2 = EP_TYPE(CTRL_EP); | ||
343 | /* | ||
344 | * See section 4.3 bullet 6: | ||
345 | * The default Max Packet size for ep0 is "8 bytes for a USB2 | ||
346 | * LS/FS/HS device or 512 bytes for a USB3 SS device" | ||
347 | * XXX: Not sure about wireless USB devices. | ||
348 | */ | ||
349 | if (udev->speed == USB_SPEED_SUPER) | ||
350 | ep0_ctx->ep_info2 |= MAX_PACKET(512); | ||
351 | else | ||
352 | ep0_ctx->ep_info2 |= MAX_PACKET(8); | ||
353 | /* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */ | ||
354 | ep0_ctx->ep_info2 |= MAX_BURST(0); | ||
355 | ep0_ctx->ep_info2 |= ERROR_COUNT(3); | ||
356 | |||
357 | ep0_ctx->deq[0] = | ||
358 | dev->ep_rings[0]->first_seg->dma; | ||
359 | ep0_ctx->deq[0] |= dev->ep_rings[0]->cycle_state; | ||
360 | ep0_ctx->deq[1] = 0; | ||
361 | |||
362 | /* Steps 7 and 8 were done in xhci_alloc_virt_device() */ | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
191 | void xhci_mem_cleanup(struct xhci_hcd *xhci) | 367 | void xhci_mem_cleanup(struct xhci_hcd *xhci) |
192 | { | 368 | { |
193 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 369 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
194 | int size; | 370 | int size; |
195 | 371 | int i; | |
196 | /* XXX: Free all the segments in the various rings */ | ||
197 | 372 | ||
198 | /* Free the Event Ring Segment Table and the actual Event Ring */ | 373 | /* Free the Event Ring Segment Table and the actual Event Ring */ |
199 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); | 374 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); |
@@ -218,16 +393,27 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
218 | xhci_ring_free(xhci, xhci->cmd_ring); | 393 | xhci_ring_free(xhci, xhci->cmd_ring); |
219 | xhci->cmd_ring = NULL; | 394 | xhci->cmd_ring = NULL; |
220 | xhci_dbg(xhci, "Freed command ring\n"); | 395 | xhci_dbg(xhci, "Freed command ring\n"); |
396 | |||
397 | for (i = 1; i < MAX_HC_SLOTS; ++i) | ||
398 | xhci_free_virt_device(xhci, i); | ||
399 | |||
221 | if (xhci->segment_pool) | 400 | if (xhci->segment_pool) |
222 | dma_pool_destroy(xhci->segment_pool); | 401 | dma_pool_destroy(xhci->segment_pool); |
223 | xhci->segment_pool = NULL; | 402 | xhci->segment_pool = NULL; |
224 | xhci_dbg(xhci, "Freed segment pool\n"); | 403 | xhci_dbg(xhci, "Freed segment pool\n"); |
404 | |||
405 | if (xhci->device_pool) | ||
406 | dma_pool_destroy(xhci->device_pool); | ||
407 | xhci->device_pool = NULL; | ||
408 | xhci_dbg(xhci, "Freed device context pool\n"); | ||
409 | |||
225 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]); | 410 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]); |
226 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]); | 411 | xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]); |
227 | if (xhci->dcbaa) | 412 | if (xhci->dcbaa) |
228 | pci_free_consistent(pdev, sizeof(*xhci->dcbaa), | 413 | pci_free_consistent(pdev, sizeof(*xhci->dcbaa), |
229 | xhci->dcbaa, xhci->dcbaa->dma); | 414 | xhci->dcbaa, xhci->dcbaa->dma); |
230 | xhci->dcbaa = NULL; | 415 | xhci->dcbaa = NULL; |
416 | |||
231 | xhci->page_size = 0; | 417 | xhci->page_size = 0; |
232 | xhci->page_shift = 0; | 418 | xhci->page_shift = 0; |
233 | } | 419 | } |
@@ -280,8 +466,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
280 | goto fail; | 466 | goto fail; |
281 | memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); | 467 | memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); |
282 | xhci->dcbaa->dma = dma; | 468 | xhci->dcbaa->dma = dma; |
283 | xhci_dbg(xhci, "// Setting device context base array address to 0x%x\n", | 469 | xhci_dbg(xhci, "// Device context base array address = 0x%x (DMA), 0x%x (virt)\n", |
284 | xhci->dcbaa->dma); | 470 | xhci->dcbaa->dma, (unsigned int) xhci->dcbaa); |
285 | xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]); | 471 | xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]); |
286 | xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]); | 472 | xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]); |
287 | 473 | ||
@@ -293,7 +479,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
293 | */ | 479 | */ |
294 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, | 480 | xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, |
295 | SEGMENT_SIZE, 64, xhci->page_size); | 481 | SEGMENT_SIZE, 64, xhci->page_size); |
296 | if (!xhci->segment_pool) | 482 | /* See Table 46 and Note on Figure 55 */ |
483 | /* FIXME support 64-byte contexts */ | ||
484 | xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, | ||
485 | sizeof(struct xhci_device_control), | ||
486 | 64, xhci->page_size); | ||
487 | if (!xhci->segment_pool || !xhci->device_pool) | ||
297 | goto fail; | 488 | goto fail; |
298 | 489 | ||
299 | /* Set up the command ring to have one segments for now. */ | 490 | /* Set up the command ring to have one segments for now. */ |
@@ -385,6 +576,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
385 | * something other than the default (~1ms minimum between interrupts). | 576 | * something other than the default (~1ms minimum between interrupts). |
386 | * See section 5.5.1.2. | 577 | * See section 5.5.1.2. |
387 | */ | 578 | */ |
579 | init_completion(&xhci->addr_dev); | ||
580 | for (i = 0; i < MAX_HC_SLOTS; ++i) | ||
581 | xhci->devs[i] = 0; | ||
388 | 582 | ||
389 | return 0; | 583 | return 0; |
390 | fail: | 584 | fail: |