Here is the non-controversial part of the patch I posted last week.
It just gets rid of a few places where DMA is done to variables on the
stack. After discussion on lkml, I think we agreed that DMA into the
middle of kmalloc()'ed structs is wrong and should be fixed with
alignment macros. I'll send out a separate patch to do that.
Patch is against 2.5.19-pre10.
Thanks,
Roland
diff -Naur linux-2.4.19-pre10.orig/drivers/usb/hub.c
linux-2.4.19-pre10/drivers/usb/hub.c
--- linux-2.4.19-pre10.orig/drivers/usb/hub.c Wed Jun 12 15:08:56 2002
+++ linux-2.4.19-pre10/drivers/usb/hub.c Wed Jun 12 15:16:28 2002
@@ -155,7 +155,7 @@
static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor
*endpoint)
{
struct usb_device *dev = hub->dev;
- struct usb_hub_status hubstatus;
+ struct usb_hub_status *hubstatus;
char portstr[USB_MAXCHILDREN + 1];
unsigned int pipe;
int i, maxp, ret;
@@ -258,20 +258,29 @@
dbg("port removable status: %s", portstr);
- ret = usb_get_hub_status(dev, &hubstatus);
+ hubstatus = kmalloc(sizeof *hubstatus, GFP_KERNEL);
+ if (!hubstatus) {
+ err("Unable to allocate hubstatus");
+ kfree(hub->descriptor);
+ return -1;
+ }
+ ret = usb_get_hub_status(dev, hubstatus);
if (ret < 0) {
err("Unable to get hub status (err = %d)", ret);
+ kfree(hubstatus);
kfree(hub->descriptor);
return -1;
}
- le16_to_cpus(&hubstatus.wHubStatus);
+ le16_to_cpus(&hubstatus->wHubStatus);
dbg("local power source is %s",
- (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" :
"good");
+ (hubstatus->wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" :
+"good");
dbg("%sover-current condition exists",
- (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+ (hubstatus->wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+
+ kfree(hubstatus);
/* Start the interrupt endpoint */
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
@@ -782,7 +791,7 @@
struct list_head *tmp;
struct usb_device *dev;
struct usb_hub *hub;
- struct usb_hub_status hubsts;
+ struct usb_hub_status *hubsts;
u16 hubstatus;
u16 hubchange;
u16 portstatus;
@@ -872,21 +881,27 @@
} /* end for i */
/* deal with hub status changes */
- if (usb_get_hub_status(dev, &hubsts) < 0)
- err("get_hub_status failed");
- else {
- hubstatus = le16_to_cpup(&hubsts.wHubStatus);
- hubchange = le16_to_cpup(&hubsts.wHubChange);
- if (hubchange & HUB_CHANGE_LOCAL_POWER) {
- dbg("hub power change");
- usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
- }
- if (hubchange & HUB_CHANGE_OVERCURRENT) {
- dbg("hub overcurrent change");
- wait_ms(500); /* Cool down */
- usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
- usb_hub_power_on(hub);
+ hubsts = kmalloc(sizeof *hubsts, GFP_KERNEL);
+ if (!hubsts) {
+ err("couldn't allocate hubsts");
+ } else {
+ if (usb_get_hub_status(dev, hubsts) < 0)
+ err("get_hub_status failed");
+ else {
+ hubstatus = le16_to_cpup(&hubsts->wHubStatus);
+ hubchange = le16_to_cpup(&hubsts->wHubChange);
+ if (hubchange & HUB_CHANGE_LOCAL_POWER) {
+ dbg("hub power change");
+ usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
+ }
+ if (hubchange & HUB_CHANGE_OVERCURRENT) {
+ dbg("hub overcurrent change");
+ wait_ms(500); /* Cool down */
+ usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
+ usb_hub_power_on(hub);
+ }
}
+ kfree(hubsts);
}
up(&hub->khubd_sem);
} /* end while (1) */
@@ -995,7 +1010,7 @@
int usb_reset_device(struct usb_device *dev)
{
struct usb_device *parent = dev->parent;
- struct usb_device_descriptor descriptor;
+ struct usb_device_descriptor *descriptor;
int i, ret, port = -1;
if (!parent) {
@@ -1044,17 +1059,22 @@
* If nothing changed, we reprogram the configuration and then
* the alternate settings.
*/
+ descriptor = kmalloc(sizeof *descriptor, GFP_NOIO);
+ if (!descriptor) {
+ return -ENOMEM;
+ }
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
sizeof(descriptor));
if (ret < 0)
return ret;
- le16_to_cpus(&descriptor.bcdUSB);
- le16_to_cpus(&descriptor.idVendor);
- le16_to_cpus(&descriptor.idProduct);
- le16_to_cpus(&descriptor.bcdDevice);
+ le16_to_cpus(&descriptor->bcdUSB);
+ le16_to_cpus(&descriptor->idVendor);
+ le16_to_cpus(&descriptor->idProduct);
+ le16_to_cpus(&descriptor->bcdDevice);
- if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) {
+ if (memcmp(&dev->descriptor, descriptor, sizeof(descriptor))) {
+ kfree(descriptor);
usb_destroy_configuration(dev);
ret = usb_get_device_descriptor(dev);
@@ -1083,6 +1103,8 @@
return 1;
}
+
+ kfree(descriptor);
ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
if (ret < 0) {
diff -Naur linux-2.4.19-pre10.orig/drivers/usb/storage/transport.c
linux-2.4.19-pre10/drivers/usb/storage/transport.c
--- linux-2.4.19-pre10.orig/drivers/usb/storage/transport.c Wed Jun 12 15:08:56
2002
+++ linux-2.4.19-pre10/drivers/usb/storage/transport.c Wed Jun 12 16:22:39 2002
@@ -1040,10 +1040,15 @@
/* Determine what the maximum LUN supported is */
int usb_stor_Bulk_max_lun(struct us_data *us)
{
- unsigned char data;
+ unsigned char *data;
int result;
int pipe;
+ data = kmalloc(sizeof *data, GFP_KERNEL);
+ if (!data) {
+ return 0;
+ }
+
/* issue the command -- use usb_control_msg() because
* the state machine is not yet alive */
pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
@@ -1051,14 +1056,19 @@
US_BULK_GET_MAX_LUN,
USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE,
- 0, us->ifnum, &data, sizeof(data), HZ);
+ 0, us->ifnum, data, sizeof(data), HZ);
US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
- result, data);
+ result, *data);
/* if we have a successful request, return the result */
- if (result == 1)
- return data;
+ if (result == 1) {
+ result = *data;
+ kfree(data);
+ return result;
+ } else {
+ kfree(data);
+ }
/* if we get a STALL, clear the stall */
if (result == -EPIPE) {
@@ -1077,41 +1087,54 @@
int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
{
- struct bulk_cb_wrap bcb;
- struct bulk_cs_wrap bcs;
+ struct bulk_cb_wrap *bcb;
+ struct bulk_cs_wrap *bcs;
int result;
int pipe;
int partial;
+ int ret = USB_STOR_TRANSPORT_ERROR;
+
+ bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+ if (!bcb) {
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+ if (!bcs) {
+ kfree(bcb);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
/* set up the command wrapper */
- bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb.DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb));
- bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
- bcb.Tag = srb->serial_number;
- bcb.Lun = srb->cmnd[1] >> 5;
+ bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ bcb->DataTransferLength = cpu_to_le32(usb_stor_transfer_length(srb));
+ bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
+ bcb->Tag = srb->serial_number;
+ bcb->Lun = srb->cmnd[1] >> 5;
if (us->flags & US_FL_SCM_MULT_TARG)
- bcb.Lun |= srb->target << 4;
- bcb.Length = srb->cmd_len;
+ bcb->Lun |= srb->target << 4;
+ bcb->Length = srb->cmd_len;
/* construct the pipe handle */
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
/* copy the command payload */
- memset(bcb.CDB, 0, sizeof(bcb.CDB));
- memcpy(bcb.CDB, srb->cmnd, bcb.Length);
+ memset(bcb->CDB, 0, sizeof(bcb->CDB));
+ memcpy(bcb->CDB, srb->cmnd, bcb->Length);
/* send it to out endpoint */
US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
- le32_to_cpu(bcb.Signature), bcb.Tag,
- (bcb.Lun >> 4), (bcb.Lun & 0x0F),
- bcb.DataTransferLength, bcb.Flags, bcb.Length);
- result = usb_stor_bulk_msg(us, &bcb, pipe, US_BULK_CB_WRAP_LEN,
+ le32_to_cpu(bcb->Signature), bcb->Tag,
+ (bcb->Lun >> 4), (bcb->Lun & 0x0F),
+ bcb->DataTransferLength, bcb->Flags, bcb->Length);
+ result = usb_stor_bulk_msg(us, bcb, pipe, US_BULK_CB_WRAP_LEN,
&partial);
US_DEBUGP("Bulk command transfer result=%d\n", result);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
/* if we stall, we need to clear it before we go on */
if (result == -EPIPE) {
@@ -1119,25 +1142,30 @@
result = usb_stor_clear_halt(us, pipe);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
result = -EPIPE;
} else if (result) {
/* unknown error -- we've got a problem */
- return USB_STOR_TRANSPORT_ERROR;
+ ret = USB_STOR_TRANSPORT_ERROR;
+ goto out;
}
/* if the command transfered well, then we go to the data stage */
if (result == 0) {
/* send/receive data payload, if there is any */
- if (bcb.DataTransferLength) {
+ if (bcb->DataTransferLength) {
usb_stor_transfer(srb, us);
result = srb->result;
US_DEBUGP("Bulk data transfer result 0x%x\n", result);
/* if it was aborted, we need to indicate that */
- if (result == US_BULK_TRANSFER_ABORTED)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == US_BULK_TRANSFER_ABORTED) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
}
}
@@ -1150,12 +1178,14 @@
/* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n");
- result = usb_stor_bulk_msg(us, &bcs, pipe, US_BULK_CS_WRAP_LEN,
+ result = usb_stor_bulk_msg(us, bcs, pipe, US_BULK_CS_WRAP_LEN,
&partial);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
/* did the attempt to read the CSW fail? */
if (result == -EPIPE) {
@@ -1163,17 +1193,21 @@
result = usb_stor_clear_halt(us, pipe);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
/* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n");
- result = usb_stor_bulk_msg(us, &bcs, pipe,
+ result = usb_stor_bulk_msg(us, bcs, pipe,
US_BULK_CS_WRAP_LEN, &partial);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ goto out;
+ }
/* if it fails again, we need a reset and return an error*/
if (result == -EPIPE) {
@@ -1181,48 +1215,60 @@
result = usb_stor_clear_halt(us, pipe);
/* if the command was aborted, indicate that */
- if (result == -ENOENT)
- return USB_STOR_TRANSPORT_ABORTED;
- return USB_STOR_TRANSPORT_ERROR;
+ if (result == -ENOENT) {
+ ret = USB_STOR_TRANSPORT_ABORTED;
+ } else {
+ ret = USB_STOR_TRANSPORT_ERROR;
+ }
+ goto out;
}
}
/* if we still have a failure at this point, we're in trouble */
US_DEBUGP("Bulk status result = %d\n", result);
if (result) {
- return USB_STOR_TRANSPORT_ERROR;
+ ret = USB_STOR_TRANSPORT_ERROR;
+ goto out;
}
/* check bulk status */
US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
- le32_to_cpu(bcs.Signature), bcs.Tag,
- bcs.Residue, bcs.Status);
- if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
- bcs.Tag != bcb.Tag ||
- bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+ le32_to_cpu(bcs->Signature), bcs->Tag,
+ bcs->Residue, bcs->Status);
+ if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
+ bcs->Tag != bcb->Tag ||
+ bcs->Status > US_BULK_STAT_PHASE || partial != 13) {
US_DEBUGP("Bulk logical error\n");
- return USB_STOR_TRANSPORT_ERROR;
+ ret = USB_STOR_TRANSPORT_ERROR;
+ goto out;
}
/* based on the status code, we report good or bad */
- switch (bcs.Status) {
+ switch (bcs->Status) {
case US_BULK_STAT_OK:
/* command good -- note that data could be short */
- return USB_STOR_TRANSPORT_GOOD;
+ ret = USB_STOR_TRANSPORT_GOOD;
+ goto out;
case US_BULK_STAT_FAIL:
/* command failed */
- return USB_STOR_TRANSPORT_FAILED;
+ ret = USB_STOR_TRANSPORT_FAILED;
+ goto out;
case US_BULK_STAT_PHASE:
/* phase error -- note that a transport reset will be
* invoked by the invoke_transport() function
*/
- return USB_STOR_TRANSPORT_ERROR;
+ ret = USB_STOR_TRANSPORT_ERROR;
+ goto out;
}
/* we should never get here, but if we do, we're in trouble */
- return USB_STOR_TRANSPORT_ERROR;
+
+ out:
+ kfree(bcb);
+ kfree(bcs);
+ return ret;
}
/***********************************************************************
_______________________________________________________________
Sponsored by:
ThinkGeek at http://www.ThinkGeek.com/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel