mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 19:26:25 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: USB: gadget: Fix EEM driver comments and VID/PID usb-storage: Workaround devices with bogus sense size USB: ehci: Fix IST boundary checking interval math. USB: option: Support for AIRPLUS MCD650 Datacard USB: whci-hcd: always do an update after processing a halted qTD USB: whci-hcd: handle early deletion of endpoints USB: wusb: don't use the stack to read security descriptor USB: rename Documentation/ABI/.../sysfs-class-usb_host
This commit is contained in:
commit
59c0b586ae
8 changed files with 82 additions and 52 deletions
|
@ -1,4 +1,4 @@
|
|||
What: /sys/class/usb_host/usb_hostN/wusb_chid
|
||||
What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_chid
|
||||
Date: July 2008
|
||||
KernelVersion: 2.6.27
|
||||
Contact: David Vrabel <david.vrabel@csr.com>
|
||||
|
@ -9,7 +9,7 @@ Description:
|
|||
|
||||
Set an all zero CHID to stop the host controller.
|
||||
|
||||
What: /sys/class/usb_host/usb_hostN/wusb_trust_timeout
|
||||
What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_trust_timeout
|
||||
Date: July 2008
|
||||
KernelVersion: 2.6.27
|
||||
Contact: David Vrabel <david.vrabel@csr.com>
|
|
@ -61,11 +61,6 @@
|
|||
* simpler, Microsoft pushes their own approach: RNDIS. The published
|
||||
* RNDIS specs are ambiguous and appear to be incomplete, and are also
|
||||
* needlessly complex. They borrow more from CDC ACM than CDC ECM.
|
||||
*
|
||||
* While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet
|
||||
* interface to the target, CDC EEM was designed to use ethernet over the USB
|
||||
* link between the host and target. CDC EEM is implemented as an alternative
|
||||
* to those other protocols when that communication model is more appropriate
|
||||
*/
|
||||
|
||||
#define DRIVER_DESC "Ethernet Gadget"
|
||||
|
@ -157,8 +152,8 @@ static inline bool has_rndis(void)
|
|||
#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
|
||||
|
||||
/* For EEM gadgets */
|
||||
#define EEM_VENDOR_NUM 0x0525 /* INVALID - NEEDS TO BE ALLOCATED */
|
||||
#define EEM_PRODUCT_NUM 0xa4a1 /* INVALID - NEEDS TO BE ALLOCATED */
|
||||
#define EEM_VENDOR_NUM 0x1d6b /* Linux Foundation */
|
||||
#define EEM_PRODUCT_NUM 0x0102 /* EEM Gadget */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -1400,6 +1400,10 @@ iso_stream_schedule (
|
|||
goto fail;
|
||||
}
|
||||
|
||||
period = urb->interval;
|
||||
if (!stream->highspeed)
|
||||
period <<= 3;
|
||||
|
||||
now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
|
||||
|
||||
/* when's the last uframe this urb could start? */
|
||||
|
@ -1417,8 +1421,8 @@ iso_stream_schedule (
|
|||
|
||||
/* Fell behind (by up to twice the slop amount)? */
|
||||
if (start >= max - 2 * 8 * SCHEDULE_SLOP)
|
||||
start += stream->interval * DIV_ROUND_UP(
|
||||
max - start, stream->interval) - mod;
|
||||
start += period * DIV_ROUND_UP(
|
||||
max - start, period) - mod;
|
||||
|
||||
/* Tried to schedule too far into the future? */
|
||||
if (unlikely((start + sched->span) >= max)) {
|
||||
|
@ -1441,10 +1445,6 @@ iso_stream_schedule (
|
|||
|
||||
/* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
|
||||
|
||||
period = urb->interval;
|
||||
if (!stream->highspeed)
|
||||
period <<= 3;
|
||||
|
||||
/* find a uframe slot with enough bandwidth */
|
||||
for (; start < (stream->next_uframe + period); start++) {
|
||||
int enough_space;
|
||||
|
|
|
@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
|
|||
if (status & QTD_STS_HALTED) {
|
||||
/* Ug, an error. */
|
||||
process_halted_qtd(whc, qset, td);
|
||||
/* A halted qTD always triggers an update
|
||||
because the qset was either removed or
|
||||
reactivated. */
|
||||
update |= WHC_UPDATE_UPDATED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
|
|||
struct whc_urb *wurb = urb->hcpriv;
|
||||
struct whc_qset *qset = wurb->qset;
|
||||
struct whc_std *std, *t;
|
||||
bool has_qtd = false;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
|
|||
goto out;
|
||||
|
||||
list_for_each_entry_safe(std, t, &qset->stds, list_node) {
|
||||
if (std->urb == urb)
|
||||
if (std->urb == urb) {
|
||||
if (std->qtd)
|
||||
has_qtd = true;
|
||||
qset_free_std(whc, std);
|
||||
else
|
||||
} else
|
||||
std->qtd = NULL; /* so this std is re-added when the qset is */
|
||||
}
|
||||
|
||||
asl_qset_remove(whc, qset);
|
||||
wurb->status = status;
|
||||
wurb->is_async = true;
|
||||
queue_work(whc->workqueue, &wurb->dequeue_work);
|
||||
|
||||
if (has_qtd) {
|
||||
asl_qset_remove(whc, qset);
|
||||
wurb->status = status;
|
||||
wurb->is_async = true;
|
||||
queue_work(whc->workqueue, &wurb->dequeue_work);
|
||||
} else
|
||||
qset_remove_urb(whc, qset, urb, status);
|
||||
out:
|
||||
spin_unlock_irqrestore(&whc->lock, flags);
|
||||
|
||||
|
|
|
@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
|
|||
if (status & QTD_STS_HALTED) {
|
||||
/* Ug, an error. */
|
||||
process_halted_qtd(whc, qset, td);
|
||||
/* A halted qTD always triggers an update
|
||||
because the qset was either removed or
|
||||
reactivated. */
|
||||
update |= WHC_UPDATE_UPDATED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
|
|||
struct whc_urb *wurb = urb->hcpriv;
|
||||
struct whc_qset *qset = wurb->qset;
|
||||
struct whc_std *std, *t;
|
||||
bool has_qtd = false;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
|
|||
goto out;
|
||||
|
||||
list_for_each_entry_safe(std, t, &qset->stds, list_node) {
|
||||
if (std->urb == urb)
|
||||
if (std->urb == urb) {
|
||||
if (std->qtd)
|
||||
has_qtd = true;
|
||||
qset_free_std(whc, std);
|
||||
else
|
||||
} else
|
||||
std->qtd = NULL; /* so this std is re-added when the qset is */
|
||||
}
|
||||
|
||||
pzl_qset_remove(whc, qset);
|
||||
wurb->status = status;
|
||||
wurb->is_async = false;
|
||||
queue_work(whc->workqueue, &wurb->dequeue_work);
|
||||
|
||||
if (has_qtd) {
|
||||
pzl_qset_remove(whc, qset);
|
||||
update_pzl_hw_view(whc);
|
||||
wurb->status = status;
|
||||
wurb->is_async = false;
|
||||
queue_work(whc->workqueue, &wurb->dequeue_work);
|
||||
} else
|
||||
qset_remove_urb(whc, qset, urb, status);
|
||||
out:
|
||||
spin_unlock_irqrestore(&whc->lock, flags);
|
||||
|
||||
|
|
|
@ -328,6 +328,9 @@ static int option_resume(struct usb_serial *serial);
|
|||
#define ALCATEL_VENDOR_ID 0x1bbb
|
||||
#define ALCATEL_PRODUCT_X060S 0x0000
|
||||
|
||||
/* Airplus products */
|
||||
#define AIRPLUS_VENDOR_ID 0x1011
|
||||
#define AIRPLUS_PRODUCT_MCD650 0x3198
|
||||
|
||||
static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
|
@ -589,6 +592,7 @@ static struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
|
||||
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
|
|
@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
|
|||
/* device supports and needs bigger sense buffer */
|
||||
if (us->fflags & US_FL_SANE_SENSE)
|
||||
sense_size = ~0;
|
||||
|
||||
Retry_Sense:
|
||||
US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
|
||||
|
||||
scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
|
||||
|
@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
|
|||
srb->result = DID_ABORT << 16;
|
||||
goto Handle_Errors;
|
||||
}
|
||||
|
||||
/* Some devices claim to support larger sense but fail when
|
||||
* trying to request it. When a transport failure happens
|
||||
* using US_FS_SANE_SENSE, we always retry with a standard
|
||||
* (small) sense request. This fixes some USB GSM modems
|
||||
*/
|
||||
if (temp_result == USB_STOR_TRANSPORT_FAILED &&
|
||||
(us->fflags & US_FL_SANE_SENSE) &&
|
||||
sense_size != US_SENSE_SIZE) {
|
||||
US_DEBUGP("-- auto-sense failure, retry small sense\n");
|
||||
sense_size = US_SENSE_SIZE;
|
||||
goto Retry_Sense;
|
||||
}
|
||||
|
||||
/* Other failures */
|
||||
if (temp_result != USB_STOR_TRANSPORT_GOOD) {
|
||||
US_DEBUGP("-- auto-sense failure\n");
|
||||
|
||||
|
|
|
@ -200,35 +200,40 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
|
|||
{
|
||||
int result, bytes, secd_size;
|
||||
struct device *dev = &usb_dev->dev;
|
||||
struct usb_security_descriptor secd;
|
||||
struct usb_security_descriptor *secd;
|
||||
const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
|
||||
void *secd_buf;
|
||||
const void *itr, *top;
|
||||
char buf[64];
|
||||
|
||||
secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
|
||||
if (secd == NULL) {
|
||||
result = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
|
||||
0, &secd, sizeof(secd));
|
||||
0, secd, sizeof(struct usb_security_descriptor));
|
||||
if (result < sizeof(secd)) {
|
||||
dev_err(dev, "Can't read security descriptor or "
|
||||
"not enough data: %d\n", result);
|
||||
goto error_secd;
|
||||
goto out;
|
||||
}
|
||||
secd_size = le16_to_cpu(secd.wTotalLength);
|
||||
secd_buf = kmalloc(secd_size, GFP_KERNEL);
|
||||
if (secd_buf == NULL) {
|
||||
secd_size = le16_to_cpu(secd->wTotalLength);
|
||||
secd = krealloc(secd, secd_size, GFP_KERNEL);
|
||||
if (secd == NULL) {
|
||||
dev_err(dev, "Can't allocate space for security descriptors\n");
|
||||
goto error_secd_alloc;
|
||||
goto out;
|
||||
}
|
||||
result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
|
||||
0, secd_buf, secd_size);
|
||||
0, secd, secd_size);
|
||||
if (result < secd_size) {
|
||||
dev_err(dev, "Can't read security descriptor or "
|
||||
"not enough data: %d\n", result);
|
||||
goto error_secd_all;
|
||||
goto out;
|
||||
}
|
||||
bytes = 0;
|
||||
itr = secd_buf + sizeof(secd);
|
||||
top = secd_buf + result;
|
||||
itr = &secd[1];
|
||||
top = (void *)secd + result;
|
||||
while (itr < top) {
|
||||
etd = itr;
|
||||
if (top - itr < sizeof(*etd)) {
|
||||
|
@ -259,24 +264,16 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
|
|||
dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
|
||||
"can't use!\n");
|
||||
result = -EINVAL;
|
||||
goto error_no_ccm1;
|
||||
goto out;
|
||||
}
|
||||
wusb_dev->ccm1_etd = *ccm1_etd;
|
||||
dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
|
||||
buf, wusb_et_name(ccm1_etd->bEncryptionType),
|
||||
ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
|
||||
result = 0;
|
||||
kfree(secd_buf);
|
||||
out:
|
||||
kfree(secd);
|
||||
return result;
|
||||
|
||||
|
||||
error_no_ccm1:
|
||||
error_secd_all:
|
||||
kfree(secd_buf);
|
||||
error_secd_alloc:
|
||||
error_secd:
|
||||
goto out;
|
||||
}
|
||||
|
||||
void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
|
||||
|
|
Loading…
Reference in a new issue