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)
/* Maybe kick BIOS off this hardware. Then reset, so we won't get
* interrupts from any previous setup.
*/
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
reset_hc(uhci);
pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
return 0;
}
......
......@@ -189,8 +189,7 @@ struct udsl_vcc_data {
struct atm_vcc *vcc;
/* raw cell reassembly */
struct sk_buff *skb;
unsigned int max_pdu;
struct sk_buff *sarb;
};
/* send */
......@@ -314,12 +313,10 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
{
struct udsl_vcc_data *cached_vcc = NULL;
struct atm_vcc *vcc;
struct sk_buff *skb;
struct sk_buff *sarb;
struct udsl_vcc_data *vcc_data;
int cached_vci = 0;
unsigned int i;
unsigned int length;
unsigned int pdu_length;
int pti;
int vci;
short cached_vpi = 0;
......@@ -344,74 +341,73 @@ static void udsl_extract_cells (struct udsl_instance_data *instance, unsigned ch
}
vcc = vcc_data->vcc;
sarb = vcc_data->sarb;
if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", 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);
if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
dbg ("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
/* discard cells already received */
skb_trim (skb, 0);
DEBUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
skb_trim (sarb, 0);
}
memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
__skb_put (skb, ATM_CELL_PAYLOAD);
memcpy (sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
__skb_put (sarb, ATM_CELL_PAYLOAD);
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];
/* guard against overflow */
if (length > ATM_MAX_AAL5_PDU) {
dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
goto drop;
dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
atomic_inc (&vcc->stats->rx_err);
goto out;
}
pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
if (skb->len < pdu_length) {
dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
goto drop;
if (sarb->len < pdu_length) {
dbg ("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
atomic_inc (&vcc->stats->rx_err);
goto out;
}
if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
goto drop;
if (crc32_be (~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
atomic_inc (&vcc->stats->rx_err);
goto out;
}
if (!atm_charge (vcc, skb->truesize)) {
dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
goto drop_no_stats; /* atm_charge increments rx_drop */
}
vdbg ("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
/* now that we are sure to send the skb, it is ok to change skb->data */
if (skb->len > pdu_length)
skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
if (!(skb = dev_alloc_skb (length))) {
dbg ("udsl_extract_cells: no memory for skb (length: %u)!", length);
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);
vcc->push (vcc, skb);
vcc_data->skb = NULL;
PACKETDEBUG (skb->data, skb->len);
continue;
vcc->push (vcc, skb);
drop:
atomic_inc (&vcc->stats->rx_err);
drop_no_stats:
skb_trim (skb, 0);
atomic_inc (&vcc->stats->rx);
out:
skb_trim (sarb, 0);
}
}
}
......@@ -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_vcc_data *new;
unsigned int max_pdu;
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)
return -EINVAL;
/* 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;
}
if (!instance->firmware_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)
down (&instance->serialize); /* vs self, udsl_atm_close */
if (udsl_find_vcc (instance, vpi, vci)) {
dbg ("udsl_atm_open: %hd/%d already in use!", vpi, vci);
up (&instance->serialize);
return -EADDRINUSE;
}
if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
dbg ("udsl_atm_open: no memory for vcc_data!");
up (&instance->serialize);
return -ENOMEM;
}
......@@ -907,7 +908,15 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
new->vcc = vcc;
new->vpi = vpi;
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->vpi = vpi;
......@@ -925,7 +934,7 @@ static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
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;
}
......@@ -952,9 +961,8 @@ static void udsl_atm_close (struct atm_vcc *vcc)
list_del (&vcc_data->list);
tasklet_enable (&instance->receive_tasklet);
if (vcc_data->skb)
dev_kfree_skb (vcc_data->skb);
vcc_data->skb = NULL;
kfree_skb (vcc_data->sarb);
vcc_data->sarb = NULL;
kfree (vcc_data);
vcc->dev_data = NULL;
......@@ -1216,7 +1224,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_rcv_urbs; i++)
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 */
do {
......@@ -1252,7 +1260,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
for (i = 0; i < num_snd_urbs; i++)
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 */
do {
......@@ -1298,11 +1306,9 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static int __init udsl_usb_init (void)
{
struct sk_buff *skb; /* dummy for sizeof */
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");
return -EIO;
}
......
......@@ -101,7 +101,8 @@ struct freecom_status {
#define FCM_PACKET_IDE_READ 0xC0
/* 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
freecom_readdata (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
* doesn't hurt us to always do it now. */
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);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
......@@ -256,10 +257,10 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get the data */
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);
if (result > USB_STOR_XFER_SHORT)
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial));
......@@ -302,6 +303,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
switch (us->srb->sc_data_direction) {
case SCSI_DATA_READ:
/* catch bogus "read 0 length" case */
if (!length)
break;
/* Make sure that the status indicates that the device
* wants data as well. */
if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
......@@ -331,6 +335,9 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break;
case SCSI_DATA_WRITE:
/* catch bogus "write 0 length" case */
if (!length)
break;
/* Make sure the status indicates that the device wants to
* send us data. */
/* !!IMPLEMENT!! */
......@@ -362,6 +369,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
break;
default:
/* should never hit here -- filtered in usb.c */
US_DEBUGP ("freecom unimplemented direction: %d\n",
us->srb->sc_data_direction);
// Return fail, SCSI seems to handle this better.
......
......@@ -394,6 +394,12 @@ UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001,
"Dimage F300",
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,
"Hagiwara",
"FlashGate SmartMedia",
......@@ -542,7 +548,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
* - They don't like the INQUIRY command. So we must handle this command
* of the SCSI layer ourselves.
*/
UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x5009,
"Casio",
"QV DigitalCamera",
US_SC_8070, US_PR_CB, NULL,
......
......@@ -1038,9 +1038,9 @@ void usb_show_string(struct usb_device *dev, char *id, int index);
#define dbg(format, arg...) do {} while (0)
#endif
#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg)
#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg)
#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg)
#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
#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