Commit 1c321b9f authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.6
parents 5e2995a5 50652e8a
...@@ -2185,8 +2185,8 @@ static int uhci_reset(struct usb_hcd *hcd) ...@@ -2185,8 +2185,8 @@ static int uhci_reset(struct usb_hcd *hcd)
/* Maybe kick BIOS off this hardware. Then reset, so we won't get /* Maybe kick BIOS off this hardware. Then reset, so we won't get
* interrupts from any previous setup. * interrupts from any previous setup.
*/ */
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
reset_hc(uhci); reset_hc(uhci);
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
return 0; return 0;
} }
......
...@@ -189,8 +189,7 @@ struct udsl_vcc_data { ...@@ -189,8 +189,7 @@ struct udsl_vcc_data {
struct atm_vcc *vcc; struct atm_vcc *vcc;
/* raw cell reassembly */ /* raw cell reassembly */
struct sk_buff *skb; struct sk_buff *sarb;
unsigned int max_pdu;
}; };
/* send */ /* send */
...@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch ...@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
{ {
struct udsl_vcc_data *cached_vcc = NULL; struct udsl_vcc_data *cached_vcc = NULL;
struct atm_vcc *vcc; struct atm_vcc *vcc;
struct sk_buff *skb; struct sk_buff *sarb;
struct udsl_vcc_data *vcc_data; struct udsl_vcc_data *vcc_data;
int cached_vci = 0; int cached_vci = 0;
unsigned int i; unsigned int i;
unsigned int length;
unsigned int pdu_length;
int pti; int pti;
int vci; int vci;
short cached_vpi = 0; short cached_vpi = 0;
...@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch ...@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
} }
vcc = vcc_data->vcc; vcc = vcc_data->vcc;
sarb = vcc_data->sarb;
if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) { if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc); dbg ("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
if (pti)
atomic_inc (&vcc->stats->rx_err);
continue;
}
skb = vcc_data->skb;
if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
/* discard cells already received */ /* discard cells already received */
skb_trim (skb, 0); skb_trim (sarb, 0);
DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
} }
memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); memcpy (sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
__skb_put (skb, ATM_CELL_PAYLOAD); __skb_put (sarb, ATM_CELL_PAYLOAD);
if (pti) { if (pti) {
struct sk_buff *skb;
unsigned int length;
unsigned int pdu_length;
length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5]; length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
/* guard against overflow */ /* guard against overflow */
if (length > ATM_MAX_AAL5_PDU) { if (length > ATM_MAX_AAL5_PDU) {
dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc); dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD; pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
if (skb->len < pdu_length) { if (sarb->len < pdu_length) {
dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc); dbg ("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) { if (crc32_be (~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc); dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
goto drop; atomic_inc (&vcc->stats->rx_err);
goto out;
} }
if (!atm_charge (vcc, skb->truesize)) { vdbg ("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
goto drop_no_stats; /* atm_charge increments rx_drop */
}
/* now that we are sure to send the skb, it is ok to change skb->data */ if (!(skb = dev_alloc_skb (length))) {
if (skb->len > pdu_length) dbg ("udsl_extract_cells: no memory for skb (length: %u)!", length);
skb_pull (skb, skb->len - pdu_length); /* discard initial junk */ atomic_inc (&vcc->stats->rx_drop);
goto out;
}
skb_trim (skb, length); /* drop zero padding and trailer */ vdbg ("udsl_extract_cells: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", skb, skb->truesize);
atomic_inc (&vcc->stats->rx); if (!atm_charge (vcc, skb->truesize)) {
dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)!", skb->truesize);
dev_kfree_skb (skb);
goto out; /* atm_charge increments rx_drop */
}
PACKETDEBUG (skb->data, skb->len); memcpy (skb->data, sarb->tail - pdu_length, length);
__skb_put (skb, length);
vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize); vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
vcc->push (vcc, skb); PACKETDEBUG (skb->data, skb->len);
vcc_data->skb = NULL;
continue; vcc->push (vcc, skb);
drop: atomic_inc (&vcc->stats->rx);
atomic_inc (&vcc->stats->rx_err); out:
drop_no_stats: skb_trim (sarb, 0);
skb_trim (skb, 0);
} }
} }
} }
...@@ -871,6 +867,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -871,6 +867,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{ {
struct udsl_instance_data *instance = vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *new; struct udsl_vcc_data *new;
unsigned int max_pdu;
dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci); dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
...@@ -883,8 +880,10 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -883,8 +880,10 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL; return -EINVAL;
/* only support AAL5 */ /* only support AAL5 */
if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
return -EINVAL; return -EINVAL;
}
if (!instance->firmware_loaded) { if (!instance->firmware_loaded) {
dbg ("udsl_atm_open: firmware not loaded!"); dbg ("udsl_atm_open: firmware not loaded!");
...@@ -894,11 +893,13 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -894,11 +893,13 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
down (&instance->serialize); /* vs self, udsl_atm_close */ down (&instance->serialize); /* vs self, udsl_atm_close */
if (udsl_find_vcc (instance, vpi, vci)) { if (udsl_find_vcc (instance, vpi, vci)) {
dbg ("udsl_atm_open: %hd/%d already in use!", vpi, vci);
up (&instance->serialize); up (&instance->serialize);
return -EADDRINUSE; return -EADDRINUSE;
} }
if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) { if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
dbg ("udsl_atm_open: no memory for vcc_data!");
up (&instance->serialize); up (&instance->serialize);
return -ENOMEM; return -ENOMEM;
} }
...@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
new->vcc = vcc; new->vcc = vcc;
new->vpi = vpi; new->vpi = vpi;
new->vci = vci; new->vci = vci;
new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
/* udsl_extract_cells requires at least one cell */
max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
if (!(new->sarb = alloc_skb (max_pdu, GFP_KERNEL))) {
dbg ("udsl_atm_open: no memory for SAR buffer!");
kfree (new);
up (&instance->serialize);
return -ENOMEM;
}
vcc->dev_data = new; vcc->dev_data = new;
vcc->vpi = vpi; vcc->vpi = vpi;
...@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
tasklet_schedule (&instance->receive_tasklet); tasklet_schedule (&instance->receive_tasklet);
dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu); dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);
return 0; return 0;
} }
...@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_vcc *vcc) ...@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_vcc *vcc)
list_del (&vcc_data->list); list_del (&vcc_data->list);
tasklet_enable (&instance->receive_tasklet); tasklet_enable (&instance->receive_tasklet);
if (vcc_data->skb) kfree_skb (vcc_data->sarb);
dev_kfree_skb (vcc_data->skb); vcc_data->sarb = NULL;
vcc_data->skb = NULL;
kfree (vcc_data); kfree (vcc_data);
vcc->dev_data = NULL; vcc->dev_data = NULL;
...@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_rcv_urbs; i++) for (i = 0; i < num_rcv_urbs; i++)
if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0) if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d!", i, result);
/* wait for completion handlers to finish */ /* wait for completion handlers to finish */
do { do {
...@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_snd_urbs; i++) for (i = 0; i < num_snd_urbs; i++)
if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0) if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result); dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d!", i, result);
/* wait for completion handlers to finish */ /* wait for completion handlers to finish */
do { do {
...@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static int __init udsl_usb_init (void) static int __init udsl_usb_init (void)
{ {
struct sk_buff *skb; /* dummy for sizeof */
dbg ("udsl_usb_init: driver version " DRIVER_VERSION); dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
if (sizeof (struct udsl_control) > sizeof (skb->cb)) { if (sizeof (struct udsl_control) > sizeof (((struct sk_buff *)0)->cb)) {
printk (KERN_ERR __FILE__ ": unusable with this kernel!\n"); printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
return -EIO; return -EIO;
} }
......
...@@ -101,7 +101,8 @@ struct freecom_status { ...@@ -101,7 +101,8 @@ struct freecom_status {
#define FCM_PACKET_IDE_READ 0xC0 #define FCM_PACKET_IDE_READ 0xC0
/* All packets (except for status) are 64 bytes long. */ /* All packets (except for status) are 64 bytes long. */
#define FCM_PACKET_LENGTH 64 #define FCM_PACKET_LENGTH 64
#define FCM_STATUS_PACKET_LENGTH 4
static int static int
freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
...@@ -216,7 +217,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -216,7 +217,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* There are times we can optimize out this status read, but it /* There are times we can optimize out this status read, but it
* doesn't hurt us to always do it now. */ * doesn't hurt us to always do it now. */
result = usb_stor_bulk_transfer_buf (us, ipipe, fst, result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial); FCM_STATUS_PACKET_LENGTH, &partial);
US_DEBUGP("foo Status result %d %u\n", result, partial); US_DEBUGP("foo Status result %d %u\n", result, partial);
if (result != USB_STOR_XFER_GOOD) if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
...@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get the data */ /* get the data */
result = usb_stor_bulk_transfer_buf (us, ipipe, fst, result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
FCM_PACKET_LENGTH, &partial); FCM_STATUS_PACKET_LENGTH, &partial);
US_DEBUGP("bar Status result %d %u\n", result, partial); US_DEBUGP("bar Status result %d %u\n", result, partial);
if (result > USB_STOR_XFER_SHORT) if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial)); US_DEBUG(pdump ((void *) fst, partial));
...@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
switch (us->srb->sc_data_direction) { switch (us->srb->sc_data_direction) {
case SCSI_DATA_READ: case SCSI_DATA_READ:
/* catch bogus "read 0 length" case */
if (!length)
break;
/* Make sure that the status indicates that the device /* Make sure that the status indicates that the device
* wants data as well. */ * wants data as well. */
if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
...@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break; break;
case SCSI_DATA_WRITE: case SCSI_DATA_WRITE:
/* catch bogus "write 0 length" case */
if (!length)
break;
/* Make sure the status indicates that the device wants to /* Make sure the status indicates that the device wants to
* send us data. */ * send us data. */
/* !!IMPLEMENT!! */ /* !!IMPLEMENT!! */
...@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break; break;
default: default:
/* should never hit here -- filtered in usb.c */
US_DEBUGP ("freecom unimplemented direction: %d\n", US_DEBUGP ("freecom unimplemented direction: %d\n",
us->srb->sc_data_direction); us->srb->sc_data_direction);
// Return fail, SCSI seems to handle this better. // Return fail, SCSI seems to handle this better.
......
...@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001, ...@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
"Dimage F300", "Dimage F300",
US_SC_SCSI, US_PR_BULK, NULL, 0 ), US_SC_SCSI, US_PR_BULK, NULL, 0 ),
/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001,
"Minolta",
"DIMAGE E223",
US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100,
"Hagiwara", "Hagiwara",
"FlashGate SmartMedia", "FlashGate SmartMedia",
...@@ -542,7 +548,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, ...@@ -542,7 +548,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
* - They don't like the INQUIRY command. So we must handle this command * - They don't like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves. * of the SCSI layer ourselves.
*/ */
UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009, UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x5009,
"Casio", "Casio",
"QV DigitalCamera", "QV DigitalCamera",
US_SC_8070, US_PR_CB, NULL, US_SC_8070, US_PR_CB, NULL,
......
...@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *dev, char *id, int index); ...@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *dev, char *id, int index);
#define dbg(format, arg...) do {} while (0) #define dbg(format, arg...) do {} while (0)
#endif #endif
#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg) #define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment