forked from Minki/linux
usb/isp1760: Clean up urb enqueueing
This collects urb enqueue code that was spread out all over the place into a couple of more readable functions. Signed-off-by: Arvid Brodin <arvid.brodin@enea.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
847ed3e8f1
commit
34537731d7
@ -272,7 +272,7 @@ static void init_memory(struct isp1760_hcd *priv)
|
|||||||
payload_addr += priv->memory_pool[curr + i].size;
|
payload_addr += priv->memory_pool[curr + i].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE);
|
WARN_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
||||||
@ -280,7 +280,7 @@ static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
|||||||
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUG_ON(qtd->payload_addr);
|
WARN_ON(qtd->payload_addr);
|
||||||
|
|
||||||
if (!qtd->length)
|
if (!qtd->length)
|
||||||
return;
|
return;
|
||||||
@ -318,7 +318,7 @@ static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
|
|||||||
|
|
||||||
for (i = 0; i < BLOCKS; i++) {
|
for (i = 0; i < BLOCKS; i++) {
|
||||||
if (priv->memory_pool[i].start == qtd->payload_addr) {
|
if (priv->memory_pool[i].start == qtd->payload_addr) {
|
||||||
BUG_ON(priv->memory_pool[i].free);
|
WARN_ON(priv->memory_pool[i].free);
|
||||||
priv->memory_pool[i].free = 1;
|
priv->memory_pool[i].free = 1;
|
||||||
qtd->payload_addr = 0;
|
qtd->payload_addr = 0;
|
||||||
return;
|
return;
|
||||||
@ -379,7 +379,7 @@ static int ehci_reset(struct usb_hcd *hcd)
|
|||||||
|
|
||||||
static void qh_destroy(struct isp1760_qh *qh)
|
static void qh_destroy(struct isp1760_qh *qh)
|
||||||
{
|
{
|
||||||
BUG_ON(!list_empty(&qh->qtd_list));
|
WARN_ON(!list_empty(&qh->qtd_list));
|
||||||
kmem_cache_free(qh_cachep, qh);
|
kmem_cache_free(qh_cachep, qh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -738,23 +738,6 @@ static void transform_into_int(struct isp1760_qh *qh,
|
|||||||
transform_add_int(qh, qtd, ptd);
|
transform_add_int(qh, qtd, ptd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len,
|
|
||||||
u32 token)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
qtd->data_buffer = databuffer;
|
|
||||||
qtd->packet_type = GET_QTD_TOKEN_TYPE(token);
|
|
||||||
|
|
||||||
if (len > MAX_PAYLOAD_SIZE)
|
|
||||||
count = MAX_PAYLOAD_SIZE;
|
|
||||||
else
|
|
||||||
count = len;
|
|
||||||
|
|
||||||
qtd->length = count;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int check_error(struct usb_hcd *hcd, struct ptd *ptd)
|
static int check_error(struct usb_hcd *hcd, struct ptd *ptd)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
@ -948,9 +931,25 @@ __acquires(priv->lock)
|
|||||||
spin_lock(&priv->lock);
|
spin_lock(&priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void isp1760_qtd_free(struct isp1760_qtd *qtd)
|
static struct isp1760_qtd *qtd_alloc(gfp_t flags, struct urb *urb,
|
||||||
|
u8 packet_type)
|
||||||
{
|
{
|
||||||
BUG_ON(qtd->payload_addr);
|
struct isp1760_qtd *qtd;
|
||||||
|
|
||||||
|
qtd = kmem_cache_zalloc(qtd_cachep, flags);
|
||||||
|
if (!qtd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&qtd->qtd_list);
|
||||||
|
qtd->urb = urb;
|
||||||
|
qtd->packet_type = packet_type;
|
||||||
|
|
||||||
|
return qtd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qtd_free(struct isp1760_qtd *qtd)
|
||||||
|
{
|
||||||
|
WARN_ON(qtd->payload_addr);
|
||||||
kmem_cache_free(qtd_cachep, qtd);
|
kmem_cache_free(qtd_cachep, qtd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +964,7 @@ static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd,
|
|||||||
tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd,
|
tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd,
|
||||||
qtd_list);
|
qtd_list);
|
||||||
list_del(&qtd->qtd_list);
|
list_del(&qtd->qtd_list);
|
||||||
isp1760_qtd_free(qtd);
|
qtd_free(qtd);
|
||||||
return tmp_qtd;
|
return tmp_qtd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,210 +1293,95 @@ static void do_intl_int(struct usb_hcd *hcd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isp1760_qh *qh_make(struct usb_hcd *hcd, struct urb *urb,
|
static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len)
|
||||||
gfp_t flags)
|
|
||||||
{
|
{
|
||||||
struct isp1760_qh *qh;
|
qtd->data_buffer = databuffer;
|
||||||
int is_input, type;
|
|
||||||
|
|
||||||
qh = isp1760_qh_alloc(flags);
|
if (len > MAX_PAYLOAD_SIZE)
|
||||||
if (!qh)
|
len = MAX_PAYLOAD_SIZE;
|
||||||
return qh;
|
qtd->length = len;
|
||||||
|
|
||||||
/*
|
return qtd->length;
|
||||||
* init endpoint/device data for this QH
|
|
||||||
*/
|
|
||||||
is_input = usb_pipein(urb->pipe);
|
|
||||||
type = usb_pipetype(urb->pipe);
|
|
||||||
|
|
||||||
if (!usb_pipecontrol(urb->pipe))
|
|
||||||
usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input,
|
|
||||||
1);
|
|
||||||
return qh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void qtd_list_free(struct list_head *qtd_list)
|
||||||
* For control/bulk/interrupt, return QH with these TDs appended.
|
|
||||||
* Allocates and initializes the QH if necessary.
|
|
||||||
* Returns null if it can't allocate a QH it needs to.
|
|
||||||
* If the QH has TDs (urbs) already, that's great.
|
|
||||||
*/
|
|
||||||
static struct isp1760_qh *qh_append_tds(struct usb_hcd *hcd,
|
|
||||||
struct urb *urb, struct list_head *qtd_list, int epnum,
|
|
||||||
void **ptr)
|
|
||||||
{
|
{
|
||||||
struct isp1760_qh *qh;
|
struct isp1760_qtd *qtd, *qtd_next;
|
||||||
|
|
||||||
qh = (struct isp1760_qh *)*ptr;
|
list_for_each_entry_safe(qtd, qtd_next, qtd_list, qtd_list) {
|
||||||
if (!qh) {
|
|
||||||
/* can't sleep here, we have priv->lock... */
|
|
||||||
qh = qh_make(hcd, urb, GFP_ATOMIC);
|
|
||||||
if (!qh)
|
|
||||||
return qh;
|
|
||||||
*ptr = qh;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_splice(qtd_list, qh->qtd_list.prev);
|
|
||||||
|
|
||||||
return qh;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qtd_list_free(struct urb *urb, struct list_head *qtd_list)
|
|
||||||
{
|
|
||||||
struct list_head *entry, *temp;
|
|
||||||
|
|
||||||
list_for_each_safe(entry, temp, qtd_list) {
|
|
||||||
struct isp1760_qtd *qtd;
|
|
||||||
|
|
||||||
qtd = list_entry(entry, struct isp1760_qtd, qtd_list);
|
|
||||||
list_del(&qtd->qtd_list);
|
list_del(&qtd->qtd_list);
|
||||||
isp1760_qtd_free(qtd);
|
qtd_free(qtd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isp1760_prepare_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
|
||||||
struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p)
|
|
||||||
{
|
|
||||||
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
|
||||||
struct isp1760_qtd *qtd;
|
|
||||||
int epnum;
|
|
||||||
unsigned long flags;
|
|
||||||
struct isp1760_qh *qh = NULL;
|
|
||||||
int rc;
|
|
||||||
int qh_busy;
|
|
||||||
|
|
||||||
qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list);
|
|
||||||
epnum = urb->ep->desc.bEndpointAddress;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
if (!HCD_HW_ACCESSIBLE(hcd)) {
|
|
||||||
rc = -ESHUTDOWN;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
rc = usb_hcd_link_urb_to_ep(hcd, urb);
|
|
||||||
if (rc)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
qh = urb->ep->hcpriv;
|
|
||||||
if (qh)
|
|
||||||
qh_busy = !list_empty(&qh->qtd_list);
|
|
||||||
else
|
|
||||||
qh_busy = 0;
|
|
||||||
|
|
||||||
qh = qh_append_tds(hcd, urb, qtd_list, epnum, &urb->ep->hcpriv);
|
|
||||||
if (!qh) {
|
|
||||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qh_busy)
|
|
||||||
p(hcd, qh, qtd);
|
|
||||||
|
|
||||||
done:
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
if (!qh)
|
|
||||||
qtd_list_free(urb, qtd_list);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct isp1760_qtd *isp1760_qtd_alloc(gfp_t flags)
|
|
||||||
{
|
|
||||||
struct isp1760_qtd *qtd;
|
|
||||||
|
|
||||||
qtd = kmem_cache_zalloc(qtd_cachep, flags);
|
|
||||||
if (qtd)
|
|
||||||
INIT_LIST_HEAD(&qtd->qtd_list);
|
|
||||||
|
|
||||||
return qtd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create a list of filled qtds for this URB; won't link into qh.
|
* Packetize urb->transfer_buffer into list of packets of size wMaxPacketSize.
|
||||||
|
* Also calculate the PID type (SETUP/IN/OUT) for each packet.
|
||||||
*/
|
*/
|
||||||
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
|
||||||
static struct list_head *qh_urb_transaction(struct usb_hcd *hcd,
|
static void packetize_urb(struct usb_hcd *hcd,
|
||||||
struct urb *urb, struct list_head *head, gfp_t flags)
|
struct urb *urb, struct list_head *head, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct isp1760_qtd *qtd;
|
struct isp1760_qtd *qtd;
|
||||||
void *buf;
|
void *buf;
|
||||||
int len, maxpacket;
|
int len, maxpacketsize;
|
||||||
int is_input;
|
u8 packet_type;
|
||||||
u32 token;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* URBs map to sequences of QTDs: one logical transaction
|
* URBs map to sequences of QTDs: one logical transaction
|
||||||
*/
|
*/
|
||||||
qtd = isp1760_qtd_alloc(flags);
|
|
||||||
if (!qtd)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
list_add_tail(&qtd->qtd_list, head);
|
if (!urb->transfer_buffer && urb->transfer_buffer_length) {
|
||||||
qtd->urb = urb;
|
/* XXX This looks like usb storage / SCSI bug */
|
||||||
urb->status = -EINPROGRESS;
|
dev_err(hcd->self.controller,
|
||||||
|
"buf is null, dma is %08lx len is %d\n",
|
||||||
|
(long unsigned)urb->transfer_dma,
|
||||||
|
urb->transfer_buffer_length);
|
||||||
|
WARN_ON(1);
|
||||||
|
}
|
||||||
|
|
||||||
token = 0;
|
if (usb_pipein(urb->pipe))
|
||||||
/* for split transactions, SplitXState initialized to zero */
|
packet_type = IN_PID;
|
||||||
|
else
|
||||||
|
packet_type = OUT_PID;
|
||||||
|
|
||||||
len = urb->transfer_buffer_length;
|
|
||||||
is_input = usb_pipein(urb->pipe);
|
|
||||||
if (usb_pipecontrol(urb->pipe)) {
|
if (usb_pipecontrol(urb->pipe)) {
|
||||||
/* SETUP pid */
|
qtd = qtd_alloc(flags, urb, SETUP_PID);
|
||||||
qtd_fill(qtd, urb->setup_packet,
|
|
||||||
sizeof(struct usb_ctrlrequest),
|
|
||||||
token | SETUP_PID);
|
|
||||||
|
|
||||||
/* ... and always at least one more pid */
|
|
||||||
qtd = isp1760_qtd_alloc(flags);
|
|
||||||
if (!qtd)
|
if (!qtd)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
qtd->urb = urb;
|
qtd_fill(qtd, urb->setup_packet, sizeof(struct usb_ctrlrequest));
|
||||||
list_add_tail(&qtd->qtd_list, head);
|
list_add_tail(&qtd->qtd_list, head);
|
||||||
|
|
||||||
/* for zero length DATA stages, STATUS is always IN */
|
/* for zero length DATA stages, STATUS is always IN */
|
||||||
if (len == 0)
|
if (urb->transfer_buffer_length == 0)
|
||||||
token |= IN_PID;
|
packet_type = IN_PID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
maxpacketsize = max_packet(usb_maxpacket(urb->dev, urb->pipe,
|
||||||
* data transfer stage: buffer setup
|
usb_pipeout(urb->pipe)));
|
||||||
*/
|
|
||||||
buf = urb->transfer_buffer;
|
|
||||||
|
|
||||||
if (is_input)
|
|
||||||
token |= IN_PID;
|
|
||||||
else
|
|
||||||
token |= OUT_PID;
|
|
||||||
|
|
||||||
maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* buffer gets wrapped in one or more qtds;
|
* buffer gets wrapped in one or more qtds;
|
||||||
* last one may be "short" (including zero len)
|
* last one may be "short" (including zero len)
|
||||||
* and may serve as a control status ack
|
* and may serve as a control status ack
|
||||||
*/
|
*/
|
||||||
|
buf = urb->transfer_buffer;
|
||||||
|
len = urb->transfer_buffer_length;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int this_qtd_len;
|
int this_qtd_len;
|
||||||
|
|
||||||
if (!buf && len) {
|
qtd = qtd_alloc(flags, urb, packet_type);
|
||||||
/* XXX This looks like usb storage / SCSI bug */
|
if (!qtd)
|
||||||
dev_err(hcd->self.controller, "buf is null, dma is %08lx len is %d\n",
|
goto cleanup;
|
||||||
(long unsigned)urb->transfer_dma, len);
|
this_qtd_len = qtd_fill(qtd, buf, len);
|
||||||
WARN_ON(1);
|
list_add_tail(&qtd->qtd_list, head);
|
||||||
}
|
|
||||||
|
|
||||||
this_qtd_len = qtd_fill(qtd, buf, len, token);
|
|
||||||
len -= this_qtd_len;
|
len -= this_qtd_len;
|
||||||
buf += this_qtd_len;
|
buf += this_qtd_len;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
qtd = isp1760_qtd_alloc(flags);
|
|
||||||
if (!qtd)
|
|
||||||
goto cleanup;
|
|
||||||
qtd->urb = urb;
|
|
||||||
list_add_tail(&qtd->qtd_list, head);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1509,31 +1393,78 @@ static struct list_head *qh_urb_transaction(struct usb_hcd *hcd,
|
|||||||
|
|
||||||
if (usb_pipecontrol(urb->pipe)) {
|
if (usb_pipecontrol(urb->pipe)) {
|
||||||
one_more = 1;
|
one_more = 1;
|
||||||
/* "in" <--> "out" */
|
if (packet_type == IN_PID)
|
||||||
token ^= IN_PID;
|
packet_type = OUT_PID;
|
||||||
|
else
|
||||||
|
packet_type = IN_PID;
|
||||||
} else if (usb_pipebulk(urb->pipe)
|
} else if (usb_pipebulk(urb->pipe)
|
||||||
&& (urb->transfer_flags & URB_ZERO_PACKET)
|
&& (urb->transfer_flags & URB_ZERO_PACKET)
|
||||||
&& !(urb->transfer_buffer_length % maxpacket)) {
|
&& !(urb->transfer_buffer_length %
|
||||||
|
maxpacketsize)) {
|
||||||
one_more = 1;
|
one_more = 1;
|
||||||
}
|
}
|
||||||
if (one_more) {
|
if (one_more) {
|
||||||
qtd = isp1760_qtd_alloc(flags);
|
qtd = qtd_alloc(flags, urb, packet_type);
|
||||||
if (!qtd)
|
if (!qtd)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
qtd->urb = urb;
|
|
||||||
list_add_tail(&qtd->qtd_list, head);
|
|
||||||
|
|
||||||
/* never any data in such packets */
|
/* never any data in such packets */
|
||||||
qtd_fill(qtd, NULL, 0, token);
|
qtd_fill(qtd, NULL, 0);
|
||||||
|
list_add_tail(&qtd->qtd_list, head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qtd->status = 0;
|
return;
|
||||||
return head;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
qtd_list_free(urb, head);
|
qtd_list_free(head);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
static int enqueue_qtdlist(struct usb_hcd *hcd, struct urb *urb,
|
||||||
|
struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p)
|
||||||
|
{
|
||||||
|
struct isp1760_hcd *priv = hcd_to_priv(hcd);
|
||||||
|
struct isp1760_qtd *qtd;
|
||||||
|
struct isp1760_qh *qh = NULL;
|
||||||
|
unsigned long flags;
|
||||||
|
int qh_empty;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
|
if (!HCD_HW_ACCESSIBLE(hcd)) {
|
||||||
|
rc = -ESHUTDOWN;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
rc = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||||
|
if (rc)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
qh = urb->ep->hcpriv;
|
||||||
|
if (!qh) {
|
||||||
|
qh = isp1760_qh_alloc(GFP_ATOMIC);
|
||||||
|
if (!qh) {
|
||||||
|
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (!usb_pipecontrol(urb->pipe))
|
||||||
|
usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
|
||||||
|
!usb_pipein(urb->pipe), 1);
|
||||||
|
urb->ep->hcpriv = qh;
|
||||||
|
}
|
||||||
|
|
||||||
|
qh_empty = list_empty(&qh->qtd_list);
|
||||||
|
list_splice_tail(qtd_list, &qh->qtd_list);
|
||||||
|
if (qh_empty) {
|
||||||
|
qtd = list_entry(qtd_list->next, struct isp1760_qtd, qtd_list);
|
||||||
|
p(hcd, qh, qtd);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
if (!qh)
|
||||||
|
qtd_list_free(qtd_list);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
||||||
@ -1547,14 +1478,10 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
|||||||
switch (usb_pipetype(urb->pipe)) {
|
switch (usb_pipetype(urb->pipe)) {
|
||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
case PIPE_BULK:
|
case PIPE_BULK:
|
||||||
if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags))
|
pe = enqueue_an_ATL_packet;
|
||||||
return -ENOMEM;
|
|
||||||
pe = enqueue_an_ATL_packet;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PIPE_INTERRUPT:
|
case PIPE_INTERRUPT:
|
||||||
if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags))
|
|
||||||
return -ENOMEM;
|
|
||||||
pe = enqueue_an_INT_packet;
|
pe = enqueue_an_INT_packet;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1564,7 +1491,11 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
|
|||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isp1760_prepare_enqueue(hcd, urb, &qtd_list, mem_flags, pe);
|
packetize_urb(hcd, urb, &qtd_list, mem_flags);
|
||||||
|
if (list_empty(&qtd_list))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return enqueue_qtdlist(hcd, urb, &qtd_list, mem_flags, pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||||
@ -1605,7 +1536,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
if (!ints[i].qh)
|
if (!ints[i].qh)
|
||||||
continue;
|
continue;
|
||||||
BUG_ON(!ints[i].qtd);
|
WARN_ON(!ints[i].qtd);
|
||||||
|
|
||||||
if (ints[i].qtd->urb == urb) {
|
if (ints[i].qtd->urb == urb) {
|
||||||
u32 skip_map;
|
u32 skip_map;
|
||||||
|
Loading…
Reference in New Issue
Block a user