mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-30 02:21:15 +00:00
staging: most: hdm-usb: remove proprietary urb anchoring
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@microchip.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
888a87b5a9
commit
27e6245e35
1 changed files with 21 additions and 54 deletions
|
@ -64,17 +64,6 @@
|
||||||
#define DRCI_READ_REQ 0xA0
|
#define DRCI_READ_REQ 0xA0
|
||||||
#define DRCI_WRITE_REQ 0xA1
|
#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
|
* struct most_dci_obj - Direct Communication Interface
|
||||||
* @kobj:position in sysfs
|
* @kobj:position in sysfs
|
||||||
|
@ -116,7 +105,7 @@ struct clear_hold_work {
|
||||||
* @anchor_list_lock: locks list access
|
* @anchor_list_lock: locks list access
|
||||||
* @padding_active: indicates channel uses padding
|
* @padding_active: indicates channel uses padding
|
||||||
* @is_channel_healthy: health status table of each channel
|
* @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
|
* @io_mutex: synchronize I/O with disconnect
|
||||||
* @link_stat_timer: timer for link status reports
|
* @link_stat_timer: timer for link status reports
|
||||||
* @poll_work_obj: work for polling link status
|
* @poll_work_obj: work for polling link status
|
||||||
|
@ -137,7 +126,7 @@ struct most_dev {
|
||||||
bool padding_active[MAX_NUM_ENDPOINTS];
|
bool padding_active[MAX_NUM_ENDPOINTS];
|
||||||
bool is_channel_healthy[MAX_NUM_ENDPOINTS];
|
bool is_channel_healthy[MAX_NUM_ENDPOINTS];
|
||||||
struct clear_hold_work clear_work[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 mutex io_mutex;
|
||||||
struct timer_list link_stat_timer;
|
struct timer_list link_stat_timer;
|
||||||
struct work_struct poll_work_obj;
|
struct work_struct poll_work_obj;
|
||||||
|
@ -207,17 +196,13 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel,
|
||||||
enum mbo_status_flags status)
|
enum mbo_status_flags status)
|
||||||
{
|
{
|
||||||
struct mbo *mbo;
|
struct mbo *mbo;
|
||||||
struct buf_anchor *anchor, *tmp;
|
struct urb *urb;
|
||||||
spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */
|
spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(lock, flags);
|
spin_lock_irqsave(lock, flags);
|
||||||
list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel],
|
while ((urb = usb_get_from_anchor(&mdev->busy_urbs[channel]))) {
|
||||||
list) {
|
|
||||||
struct urb *urb = anchor->urb;
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(lock, flags);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
if (likely(urb)) {
|
|
||||||
mbo = urb->context;
|
mbo = urb->context;
|
||||||
usb_kill_urb(urb);
|
usb_kill_urb(urb);
|
||||||
if (mbo && mbo->complete) {
|
if (mbo && mbo->complete) {
|
||||||
|
@ -226,10 +211,7 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel,
|
||||||
mbo->complete(mbo);
|
mbo->complete(mbo);
|
||||||
}
|
}
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
}
|
|
||||||
spin_lock_irqsave(lock, flags);
|
spin_lock_irqsave(lock, flags);
|
||||||
list_del(&anchor->list);
|
|
||||||
kfree(anchor);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(lock, flags);
|
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)
|
static void hdm_write_completion(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct mbo *mbo = urb->context;
|
struct mbo *mbo = urb->context;
|
||||||
struct buf_anchor *anchor = mbo->priv;
|
|
||||||
struct most_dev *mdev = to_mdev(mbo->ifp);
|
struct most_dev *mdev = to_mdev(mbo->ifp);
|
||||||
unsigned int channel = mbo->hdm_channel_id;
|
unsigned int channel = mbo->hdm_channel_id;
|
||||||
struct device *dev = &mdev->usb_device->dev;
|
struct device *dev = &mdev->usb_device->dev;
|
||||||
|
@ -426,14 +407,13 @@ static void hdm_write_completion(struct urb *urb)
|
||||||
mbo->status = MBO_E_INVAL;
|
mbo->status = MBO_E_INVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
usb_unanchor_urb(urb);
|
||||||
} else {
|
} else {
|
||||||
mbo->status = MBO_SUCCESS;
|
mbo->status = MBO_SUCCESS;
|
||||||
mbo->processed_length = urb->actual_length;
|
mbo->processed_length = urb->actual_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_del(&anchor->list);
|
|
||||||
spin_unlock_irqrestore(lock, flags);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
kfree(anchor);
|
|
||||||
|
|
||||||
if (likely(mbo->complete))
|
if (likely(mbo->complete))
|
||||||
mbo->complete(mbo);
|
mbo->complete(mbo);
|
||||||
|
@ -551,7 +531,6 @@ static void hdm_write_completion(struct urb *urb)
|
||||||
static void hdm_read_completion(struct urb *urb)
|
static void hdm_read_completion(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct mbo *mbo = urb->context;
|
struct mbo *mbo = urb->context;
|
||||||
struct buf_anchor *anchor = mbo->priv;
|
|
||||||
struct most_dev *mdev = to_mdev(mbo->ifp);
|
struct most_dev *mdev = to_mdev(mbo->ifp);
|
||||||
unsigned int channel = mbo->hdm_channel_id;
|
unsigned int channel = mbo->hdm_channel_id;
|
||||||
struct device *dev = &mdev->usb_device->dev;
|
struct device *dev = &mdev->usb_device->dev;
|
||||||
|
@ -585,6 +564,7 @@ static void hdm_read_completion(struct urb *urb)
|
||||||
mbo->status = MBO_E_INVAL;
|
mbo->status = MBO_E_INVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
usb_unanchor_urb(urb);
|
||||||
} else {
|
} else {
|
||||||
mbo->processed_length = urb->actual_length;
|
mbo->processed_length = urb->actual_length;
|
||||||
mbo->status = MBO_SUCCESS;
|
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);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
kfree(anchor);
|
|
||||||
|
|
||||||
if (likely(mbo->complete))
|
if (likely(mbo->complete))
|
||||||
mbo->complete(mbo);
|
mbo->complete(mbo);
|
||||||
|
@ -623,7 +601,6 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
|
||||||
struct mbo *mbo)
|
struct mbo *mbo)
|
||||||
{
|
{
|
||||||
struct most_dev *mdev;
|
struct most_dev *mdev;
|
||||||
struct buf_anchor *anchor;
|
|
||||||
struct most_channel_config *conf;
|
struct most_channel_config *conf;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -649,15 +626,6 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
|
||||||
if (!urb)
|
if (!urb)
|
||||||
return -ENOMEM;
|
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] &&
|
if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] &&
|
||||||
hdm_add_padding(mdev, channel, mbo)) {
|
hdm_add_padding(mdev, channel, mbo)) {
|
||||||
retval = -EIO;
|
retval = -EIO;
|
||||||
|
@ -691,7 +659,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
|
||||||
|
|
||||||
lock = mdev->anchor_list_lock + channel;
|
lock = mdev->anchor_list_lock + channel;
|
||||||
spin_lock_irqsave(lock, flags);
|
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);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
|
|
||||||
retval = usb_submit_urb(urb, GFP_KERNEL);
|
retval = usb_submit_urb(urb, GFP_KERNEL);
|
||||||
|
@ -703,9 +671,8 @@ static int hdm_enqueue(struct most_interface *iface, int channel,
|
||||||
|
|
||||||
_error_1:
|
_error_1:
|
||||||
spin_lock_irqsave(lock, flags);
|
spin_lock_irqsave(lock, flags);
|
||||||
list_del(&anchor->list);
|
usb_unanchor_urb(urb);
|
||||||
spin_unlock_irqrestore(lock, flags);
|
spin_unlock_irqrestore(lock, flags);
|
||||||
kfree(anchor);
|
|
||||||
_error:
|
_error:
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -1281,9 +1248,9 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||||
if (!mdev->ep_address)
|
if (!mdev->ep_address)
|
||||||
goto exit_free2;
|
goto exit_free2;
|
||||||
|
|
||||||
mdev->anchor_list =
|
mdev->busy_urbs =
|
||||||
kcalloc(num_endpoints, sizeof(*mdev->anchor_list), GFP_KERNEL);
|
kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL);
|
||||||
if (!mdev->anchor_list)
|
if (!mdev->busy_urbs)
|
||||||
goto exit_free3;
|
goto exit_free3;
|
||||||
|
|
||||||
tmp_cap = mdev->cap;
|
tmp_cap = mdev->cap;
|
||||||
|
@ -1308,7 +1275,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||||
else
|
else
|
||||||
tmp_cap->direction = MOST_CH_TX;
|
tmp_cap->direction = MOST_CH_TX;
|
||||||
tmp_cap++;
|
tmp_cap++;
|
||||||
INIT_LIST_HEAD(&mdev->anchor_list[i]);
|
init_usb_anchor(&mdev->busy_urbs[i]);
|
||||||
spin_lock_init(&mdev->anchor_list_lock[i]);
|
spin_lock_init(&mdev->anchor_list_lock[i]);
|
||||||
err = drci_wr_reg(usb_dev,
|
err = drci_wr_reg(usb_dev,
|
||||||
DRCI_REG_BASE + DRCI_COMMAND +
|
DRCI_REG_BASE + DRCI_COMMAND +
|
||||||
|
@ -1358,7 +1325,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_free4:
|
exit_free4:
|
||||||
kfree(mdev->anchor_list);
|
kfree(mdev->busy_urbs);
|
||||||
exit_free3:
|
exit_free3:
|
||||||
kfree(mdev->ep_address);
|
kfree(mdev->ep_address);
|
||||||
exit_free2:
|
exit_free2:
|
||||||
|
@ -1399,7 +1366,7 @@ static void hdm_disconnect(struct usb_interface *interface)
|
||||||
destroy_most_dci_obj(mdev->dci);
|
destroy_most_dci_obj(mdev->dci);
|
||||||
most_deregister_interface(&mdev->iface);
|
most_deregister_interface(&mdev->iface);
|
||||||
|
|
||||||
kfree(mdev->anchor_list);
|
kfree(mdev->busy_urbs);
|
||||||
kfree(mdev->cap);
|
kfree(mdev->cap);
|
||||||
kfree(mdev->conf);
|
kfree(mdev->conf);
|
||||||
kfree(mdev->ep_address);
|
kfree(mdev->ep_address);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue