This patch removes the propietary tracking of URBs. Instead the structure usb_anchor of the USB subsystem is used. Signed-off-by: Christian Gromm <christian.gromm@xxxxxxxxxxxxx> --- drivers/staging/most/hdm-usb/hdm_usb.c | 75 ++++++++++------------------------ 1 file changed, 21 insertions(+), 54 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 5b27e96..58f65a4 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -65,17 +65,6 @@ #define DRCI_WRITE_REQ 0xA1 /** - * struct buf_anchor - used to create a list of pending URBs - * @urb: pointer to USB request block - * @list: linked list - * @urb_completion: - */ -struct buf_anchor { - struct urb *urb; - struct list_head list; -}; - -/** * struct most_dci_obj - Direct Communication Interface * @kobj:position in sysfs * @usb_device: pointer to the usb device @@ -116,7 +105,7 @@ struct clear_hold_work { * @anchor_list_lock: locks list access * @padding_active: indicates channel uses padding * @is_channel_healthy: health status table of each channel - * @anchor_list: list of anchored items + * @busy_urbs: list of anchored items * @io_mutex: synchronize I/O with disconnect * @link_stat_timer: timer for link status reports * @poll_work_obj: work for polling link status @@ -137,7 +126,7 @@ struct most_dev { bool padding_active[MAX_NUM_ENDPOINTS]; bool is_channel_healthy[MAX_NUM_ENDPOINTS]; struct clear_hold_work clear_work[MAX_NUM_ENDPOINTS]; - struct list_head *anchor_list; + struct usb_anchor *busy_urbs; struct mutex io_mutex; struct timer_list link_stat_timer; struct work_struct poll_work_obj; @@ -207,29 +196,22 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, enum mbo_status_flags status) { struct mbo *mbo; - struct buf_anchor *anchor, *tmp; + struct urb *urb; spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */ unsigned long flags; spin_lock_irqsave(lock, flags); - list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel], - list) { - struct urb *urb = anchor->urb; - + while ((urb = usb_get_from_anchor(&mdev->busy_urbs[channel]))) { spin_unlock_irqrestore(lock, flags); - if (likely(urb)) { - mbo = urb->context; - usb_kill_urb(urb); - if (mbo && mbo->complete) { - mbo->status = status; - mbo->processed_length = 0; - mbo->complete(mbo); - } - usb_free_urb(urb); + mbo = urb->context; + usb_kill_urb(urb); + if (mbo && mbo->complete) { + mbo->status = status; + mbo->processed_length = 0; + mbo->complete(mbo); } + usb_free_urb(urb); spin_lock_irqsave(lock, flags); - list_del(&anchor->list); - kfree(anchor); } spin_unlock_irqrestore(lock, flags); } @@ -394,7 +376,6 @@ static int hdm_remove_padding(struct most_dev *mdev, int channel, static void hdm_write_completion(struct urb *urb) { struct mbo *mbo = urb->context; - struct buf_anchor *anchor = mbo->priv; struct most_dev *mdev = to_mdev(mbo->ifp); unsigned int channel = mbo->hdm_channel_id; struct device *dev = &mdev->usb_device->dev; @@ -426,14 +407,13 @@ static void hdm_write_completion(struct urb *urb) mbo->status = MBO_E_INVAL; break; } + usb_unanchor_urb(urb); } else { mbo->status = MBO_SUCCESS; mbo->processed_length = urb->actual_length; } - list_del(&anchor->list); spin_unlock_irqrestore(lock, flags); - kfree(anchor); if (likely(mbo->complete)) mbo->complete(mbo); @@ -551,7 +531,6 @@ static void hdm_write_completion(struct urb *urb) static void hdm_read_completion(struct urb *urb) { struct mbo *mbo = urb->context; - struct buf_anchor *anchor = mbo->priv; struct most_dev *mdev = to_mdev(mbo->ifp); unsigned int channel = mbo->hdm_channel_id; struct device *dev = &mdev->usb_device->dev; @@ -585,6 +564,7 @@ static void hdm_read_completion(struct urb *urb) mbo->status = MBO_E_INVAL; break; } + usb_unanchor_urb(urb); } else { mbo->processed_length = urb->actual_length; mbo->status = MBO_SUCCESS; @@ -595,9 +575,7 @@ static void hdm_read_completion(struct urb *urb) } } - list_del(&anchor->list); spin_unlock_irqrestore(lock, flags); - kfree(anchor); if (likely(mbo->complete)) mbo->complete(mbo); @@ -623,7 +601,6 @@ static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mbo) { struct most_dev *mdev; - struct buf_anchor *anchor; struct most_channel_config *conf; struct device *dev; int retval = 0; @@ -649,15 +626,6 @@ static int hdm_enqueue(struct most_interface *iface, int channel, if (!urb) return -ENOMEM; - anchor = kzalloc(sizeof(*anchor), GFP_ATOMIC); - if (!anchor) { - retval = -ENOMEM; - goto _error; - } - - anchor->urb = urb; - mbo->priv = anchor; - if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] && hdm_add_padding(mdev, channel, mbo)) { retval = -EIO; @@ -691,7 +659,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, lock = mdev->anchor_list_lock + channel; spin_lock_irqsave(lock, flags); - list_add_tail(&anchor->list, &mdev->anchor_list[channel]); + usb_anchor_urb(urb, &mdev->busy_urbs[channel]); spin_unlock_irqrestore(lock, flags); retval = usb_submit_urb(urb, GFP_KERNEL); @@ -703,9 +671,8 @@ static int hdm_enqueue(struct most_interface *iface, int channel, _error_1: spin_lock_irqsave(lock, flags); - list_del(&anchor->list); + usb_unanchor_urb(urb); spin_unlock_irqrestore(lock, flags); - kfree(anchor); _error: usb_free_urb(urb); return retval; @@ -1281,9 +1248,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) if (!mdev->ep_address) goto exit_free2; - mdev->anchor_list = - kcalloc(num_endpoints, sizeof(*mdev->anchor_list), GFP_KERNEL); - if (!mdev->anchor_list) + mdev->busy_urbs = + kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL); + if (!mdev->busy_urbs) goto exit_free3; tmp_cap = mdev->cap; @@ -1308,7 +1275,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) else tmp_cap->direction = MOST_CH_TX; tmp_cap++; - INIT_LIST_HEAD(&mdev->anchor_list[i]); + init_usb_anchor(&mdev->busy_urbs[i]); spin_lock_init(&mdev->anchor_list_lock[i]); err = drci_wr_reg(usb_dev, DRCI_REG_BASE + DRCI_COMMAND + @@ -1358,7 +1325,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) return 0; exit_free4: - kfree(mdev->anchor_list); + kfree(mdev->busy_urbs); exit_free3: kfree(mdev->ep_address); exit_free2: @@ -1399,7 +1366,7 @@ static void hdm_disconnect(struct usb_interface *interface) destroy_most_dci_obj(mdev->dci); most_deregister_interface(&mdev->iface); - kfree(mdev->anchor_list); + kfree(mdev->busy_urbs); kfree(mdev->cap); kfree(mdev->conf); kfree(mdev->ep_address); -- 1.9.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel