Hi,
I tried switching our allocation APIs to:
struct urb *usb_alloc_urb(struct usb_host_endpoint *ep, size_t alloc_length,
gfp_t mem_flags);
struct urb *usb_alloc_iso_urb(struct usb_host_endpoint *ep, unsigned int
iso_packets, gfp_t mem_flags);
Unfortunately during initialisation ep->ep_dev turns out to be NULL.
Should I change the allocator or the initialisation?
Regards
Oliver
------------[ cut here ]------------
Jul 6 14:17:48 valisk kernel: kernel BUG at drivers/usb/core/urb.c:63!
Jul 6 14:17:48 valisk kernel: invalid opcode: 0000 [1] SMP
Jul 6 14:17:48 valisk kernel: CPU 0
Jul 6 14:17:48 valisk kernel: Modules linked in: ohci_hcd usbcore af_packet
cpufreq_conservative cpufreq_ondemand cpufreq_userspace cpufreq_powersave
powernow_k8 freq_table snd_pcm_o
ss snd_mixer_oss snd_seq snd_seq_device bay dock button battery ac dm_mod
atiixp pcmcia generic snd_atiixp firewire_ohci bcm43xx firewire_core crc_itu_t
snd_ac97_codec nsc_ircc ohci13
94 ac97_bus ieee1394 firmware_class ide_core irda tifm_7xx1 snd_pcm
ieee80211softmac crc_ccitt tifm_core snd_timer yenta_socket rsrc_nonstatic
ieee80211 tg3 rtc_cmos rtc_core rtc_lib
snd pcmcia_core ieee80211_crypt k8temp hwmon soundcore snd_page_alloc i2c_piix4
i2c_core shpchp pci_hotplug joydev parport_pc lp parport edd fan thermal
processor
Jul 6 14:17:48 valisk kernel: Pid: 3557, comm: insmod Not tainted
2.6.22-rc7-nomem-default #14
Jul 6 14:17:48 valisk kernel: RIP: 0010:[<ffffffff883a761f>]
[<ffffffff883a761f>] :usbcore:usb_alloc_urb+0x16/0x9f
Jul 6 14:17:48 valisk kernel: RSP: 0018:ffff81002da51bc8 EFLAGS: 00010246
Jul 6 14:17:48 valisk kernel: RAX: 0000000000000000 RBX: ffff8100381d8bc0 RCX:
0000000000000080
Jul 6 14:17:48 valisk kernel: RDX: 0000000000000010 RSI: 0000000000000012 RDI:
ffff81002da35048
Jul 6 14:17:48 valisk kernel: RBP: 0000000000000012 R08: 0000000000000100 R09:
ffff81002da35048
Jul 6 14:17:48 valisk kernel: R10: ffff81003e0690c0 R11: ffffffff8043a340 R12:
00000000fffffff4
Jul 6 14:17:48 valisk kernel: R13: 0000000000000000 R14: 0000000000000012 R15:
0000000000000080
Jul 6 14:17:48 valisk kernel: FS: 00002b37467ea6f0(0000)
GS:ffffffff80571000(0000) knlGS:0000000000000000
Jul 6 14:17:48 valisk kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
Jul 6 14:17:48 valisk kernel: CR2: 00002b2aca5670a8 CR3: 000000002d5ef000 CR4:
00000000000006e0
Jul 6 14:17:48 valisk kernel: Process insmod (pid: 3557, threadinfo
ffff81002da50000, task ffff810037c54100)
Jul 6 14:17:48 valisk kernel: Stack: ffff8100381d8bc0 ffffffff883a7dcf
0000000000000008 8000018000000006
Jul 6 14:17:48 valisk kernel: ffff81002da35000 000000000018a416
ffff810037c542e8 ffff8100381d8be0
Jul 6 14:17:48 valisk kernel: 0000000000000000 00000000ffffff01
0000000000000012 ffff81002da35000
Jul 6 14:17:48 valisk kernel: Call Trace:
Jul 6 14:17:48 valisk kernel: [<ffffffff883a7dcf>]
:usbcore:usb_control_msg+0x8b/0x101
Jul 6 14:17:48 valisk kernel: [<ffffffff883a8736>]
:usbcore:usb_get_descriptor+0x72/0xa1
Jul 6 14:17:48 valisk kernel: [<ffffffff883a8d39>]
:usbcore:usb_get_device_descriptor+0x4e/0x78
Jul 6 14:17:48 valisk kernel: [<ffffffff883a680c>]
:usbcore:usb_add_hcd+0x41c/0x53d
Jul 6 14:17:48 valisk kernel: [<ffffffff883b0044>]
:usbcore:usb_hcd_pci_probe+0x1e6/0x28e
Jul 6 14:17:48 valisk kernel: [<ffffffff8032230d>] pci_device_probe+0xe2/0x14e
Jul 6 14:17:48 valisk kernel: [<ffffffff8037e546>]
driver_probe_device+0xf7/0x174
Jul 6 14:17:48 valisk kernel: [<ffffffff8037e6d9>] __driver_attach+0x6f/0xae
Jul 6 14:17:48 valisk kernel: [<ffffffff8037e66a>] __driver_attach+0x0/0xae
Jul 6 14:17:48 valisk kernel: [<ffffffff8037e66a>] __driver_attach+0x0/0xae
Jul 6 14:17:48 valisk kernel: [<ffffffff8037d962>] bus_for_each_dev+0x43/0x6e
Jul 6 14:17:48 valisk kernel: [<ffffffff8037dc88>] bus_add_driver+0x7b/0x19d
Jul 6 14:17:48 valisk kernel: [<ffffffff803224eb>]
__pci_register_driver+0x58/0x8a
Jul 6 14:17:48 valisk kernel: [<ffffffff8024d854>]
sys_init_module+0x1630/0x1793
Jul 6 14:17:48 valisk kernel: [<ffffffff8025cf9b>]
audit_syscall_entry+0x141/0x174
Jul 6 14:17:48 valisk kernel: [<ffffffff80209cec>] tracesys+0xdc/0xe1
Jul 6 14:17:48 valisk kernel:
Jul 6 14:17:48 valisk kernel:
Jul 6 14:17:48 valisk kernel: Code: 0f 0b eb fe 48 8b 40 08 48 85 c0 75 04 0f
0b eb fe 48 8b 78
Jul 6 14:17:48 valisk kernel: RIP [<ffffffff883a761f>]
:usbcore:usb_alloc_urb+0x16/0x9f
Jul 6 14:17:48 valisk kernel: RSP <ffff81002da51bc8>
diff -urp vanilla/drivers/usb/class/cdc-acm.c isotree/drivers/usb/class/cdc-acm.c
--- vanilla/drivers/usb/class/cdc-acm.c 2007-07-04 14:14:45.000000000 +0200
+++ isotree/drivers/usb/class/cdc-acm.c 2007-07-05 13:23:20.000000000 +0200
@@ -989,7 +989,7 @@ skip_normal_probe:
goto alloc_fail4;
}
- acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
+ acm->ctrlurb = usb_alloc_urb(usb_dev->ep_in[epctrl->bEndpointAddress], ctrlsize, GFP_KERNEL);
if (!acm->ctrlurb) {
dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
goto alloc_fail5;
@@ -997,7 +997,7 @@ skip_normal_probe:
for (i = 0; i < num_rx_buf; i++) {
struct acm_ru *rcv = &(acm->ru[i]);
- if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
+ if (!(rcv->urb = usb_alloc_urb(usb_dev->ep_in[epread->bEndpointAddress], readsize, GFP_KERNEL))) {
dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
goto alloc_fail7;
}
@@ -1013,7 +1013,7 @@ skip_normal_probe:
goto alloc_fail7;
}
}
- acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
+ acm->writeurb = usb_alloc_urb(usb_dev->ep_out[epwrite->bEndpointAddress], acm->writesize, GFP_KERNEL);
if (!acm->writeurb) {
dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
goto alloc_fail7;
diff -urp vanilla/drivers/usb/core/devio.c isotree/drivers/usb/core/devio.c
--- vanilla/drivers/usb/core/devio.c 2007-07-04 16:37:09.000000000 +0200
+++ isotree/drivers/usb/core/devio.c 2007-07-05 14:23:23.000000000 +0200
@@ -207,14 +207,28 @@ err:
* async list handling
*/
-static struct async *alloc_async(unsigned int numisoframes)
+static struct async *alloc_async_iso(struct usb_host_endpoint *ep, unsigned int numisoframes)
{
unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor);
struct async *as = kzalloc(assize, GFP_KERNEL);
if (!as)
return NULL;
- as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL);
+ as->urb = usb_alloc_iso_urb(ep, numisoframes, GFP_KERNEL);
+ if (!as->urb) {
+ kfree(as);
+ return NULL;
+ }
+ return as;
+}
+
+static struct async *alloc_async(struct usb_host_endpoint *ep, size_t size)
+{
+ struct async *as = kzalloc(sizeof(struct async), GFP_KERNEL);
+
+ if (!as)
+ return NULL;
+ as->urb = usb_alloc_urb(ep, size, GFP_KERNEL);
if (!as->urb) {
kfree(as);
return NULL;
@@ -1027,10 +1041,18 @@ static int proc_do_submiturb(struct dev_
default:
return -EINVAL;
}
- if (!(as = alloc_async(uurb->number_of_packets))) {
- kfree(isopkt);
- kfree(dr);
- return -ENOMEM;
+ if (uurb->type == USBDEVFS_URB_TYPE_ISO) {
+ if (!(as = alloc_async_iso(ep, uurb->number_of_packets))) {
+ kfree(isopkt);
+ kfree(dr);
+ return -ENOMEM;
+ }
+ } else {
+ if (!(as = alloc_async(ep,uurb->buffer_length ))) {
+ kfree(isopkt);
+ kfree(dr);
+ return -ENOMEM;
+ }
}
if (!(as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL))) {
kfree(isopkt);
diff -urp vanilla/drivers/usb/core/endpoint.c isotree/drivers/usb/core/endpoint.c
--- vanilla/drivers/usb/core/endpoint.c 2007-07-04 14:09:34.000000000 +0200
+++ isotree/drivers/usb/core/endpoint.c 2007-07-05 13:56:00.000000000 +0200
@@ -19,23 +19,6 @@
static int usb_endpoint_major;
static DEFINE_IDR(endpoint_idr);
-struct ep_device {
- struct usb_endpoint_descriptor *desc;
- struct usb_device *udev;
- struct device dev;
- int minor;
-};
-#define to_ep_device(_dev) \
- container_of(_dev, struct ep_device, dev)
-
-struct ep_attribute {
- struct attribute attr;
- ssize_t (*show)(struct usb_device *,
- struct usb_endpoint_descriptor *, char *);
-};
-#define to_ep_attribute(_attr) \
- container_of(_attr, struct ep_attribute, attr)
-
#define usb_ep_attr(field, format_string) \
static ssize_t show_ep_##field(struct device *dev, \
struct device_attribute *attr, \
diff -urp vanilla/drivers/usb/core/hcd.h isotree/drivers/usb/core/hcd.h
--- vanilla/drivers/usb/core/hcd.h 2007-07-04 14:14:45.000000000 +0200
+++ isotree/drivers/usb/core/hcd.h 2007-07-04 18:27:32.000000000 +0200
@@ -187,6 +187,12 @@ struct hc_driver {
struct urb *urb,
gfp_t mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
+ struct urb * (*alloc_urb) (struct usb_hcd *hcd,
+ struct usb_host_endpoint *,
+ size_t alloc_length,
+ unsigned int num_iso_packets,
+ gfp_t mem_flags);
+ void (*free_urb) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
diff -urp vanilla/drivers/usb/core/hub.c isotree/drivers/usb/core/hub.c
--- vanilla/drivers/usb/core/hub.c 2007-07-04 14:14:45.000000000 +0200
+++ isotree/drivers/usb/core/hub.c 2007-07-05 13:48:11.000000000 +0200
@@ -818,7 +818,7 @@ static int hub_configure(struct usb_hub
if (maxp > sizeof(*hub->buffer))
maxp = sizeof(*hub->buffer);
- hub->urb = usb_alloc_urb(0, GFP_KERNEL);
+ hub->urb = usb_alloc_urb(hdev->ep_in[endpoint->bEndpointAddress], maxp, GFP_KERNEL);
if (!hub->urb) {
message = "couldn't allocate interrupt urb";
ret = -ENOMEM;
diff -urp vanilla/drivers/usb/core/message.c isotree/drivers/usb/core/message.c
--- vanilla/drivers/usb/core/message.c 2007-07-04 14:14:45.000000000 +0200
+++ isotree/drivers/usb/core/message.c 2007-07-05 14:05:31.000000000 +0200
@@ -77,7 +77,7 @@ static int usb_internal_control_msg(stru
int retv;
int length;
- urb = usb_alloc_urb(0, GFP_NOIO);
+ urb = usb_alloc_urb(usb_dev->ep_out[usb_pipeendpoint(pipe)], len, GFP_NOIO);
if (!urb)
return -ENOMEM;
@@ -215,7 +215,7 @@ int usb_bulk_msg(struct usb_device *usb_
if (!ep || len < 0)
return -EINVAL;
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(ep, len, GFP_KERNEL);
if (!urb)
return -ENOMEM;
@@ -391,7 +391,9 @@ int usb_sg_init (
for (i = 0; i < io->entries; i++) {
unsigned len;
- io->urbs [i] = usb_alloc_urb (0, mem_flags);
+ io->urbs [i] = usb_alloc_urb(
+ (usb_pipein (pipe) ? dev->ep_in : dev->ep_out)[usb_pipeendpoint(pipe)],
+ 0, mem_flags);
if (!io->urbs [i]) {
io->entries = i;
goto nomem;
diff -urp vanilla/drivers/usb/core/urb.c isotree/drivers/usb/core/urb.c
--- vanilla/drivers/usb/core/urb.c 2007-07-04 16:37:09.000000000 +0200
+++ isotree/drivers/usb/core/urb.c 2007-07-06 14:05:36.000000000 +0200
@@ -11,8 +11,10 @@
static void urb_destroy(struct kref *kref)
{
struct urb *urb = to_urb(kref);
+ struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);
+
kfree(urb->iso_packets);
- kfree(urb);
+ (hcd->driver->free_urb)(hcd, urb);
}
/**
@@ -54,24 +56,49 @@ void usb_init_urb(struct urb *urb)
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
-struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
+struct urb *usb_alloc_urb(struct usb_host_endpoint *ep, size_t alloc_length, gfp_t mem_flags)
{
struct urb *urb;
- struct usb_iso_packet_descriptor *frames = NULL;
-
- if (iso_packets) {
- frames = kmalloc(iso_packets * sizeof(struct usb_iso_packet_descriptor), mem_flags);
- if (!frames)
- return NULL;
+BUG_ON(ep == NULL);
+BUG_ON(ep->ep_dev == NULL);
+BUG_ON(ep->ep_dev->udev == NULL);
+ struct usb_device *dev = ep->ep_dev->udev;
+ struct usb_hcd *hcd = bus_to_hcd(dev->bus);
+BUG_ON(hcd == NULL);
+BUG_ON(hcd->driver == NULL);
+ if (!hcd->driver->alloc_urb) {
+ err("No allocation method");
+ return NULL;
}
+ urb = (hcd->driver->alloc_urb)(hcd, ep, alloc_length, 0, mem_flags);
+ if (!urb) {
+ err("usb_alloc_urb: failed to alloc URB");
+ return NULL;
+ }
+
+ usb_init_urb(urb);
+ return urb;
+}
+
+struct urb *usb_alloc_iso_urb(struct usb_host_endpoint *ep, unsigned int iso_packets, gfp_t mem_flags)
+{
+ struct urb *urb;
+ struct usb_iso_packet_descriptor *packets = NULL;
+ struct usb_device *dev = ep->ep_dev->udev;
+ struct usb_hcd *hcd = bus_to_hcd(dev->bus);
+
+ packets = kmalloc(iso_packets * sizeof(struct usb_iso_packet_descriptor), mem_flags);
+ if (!packets)
+ return NULL;
- urb = kmalloc(sizeof(struct urb), mem_flags);
+ urb = (hcd->driver->alloc_urb)(hcd, ep, 0, iso_packets, mem_flags);
if (!urb) {
- err("alloc_urb: kmalloc failed");
- kfree(frames);
+ err("usb_alloc_iso_urb: failed to alloc URB");
+ kfree(packets);
return NULL;
}
- urb->iso_packets = frames;
+ usb_init_urb(urb);
+ urb->iso_packets = packets;
return urb;
}
@@ -488,6 +515,7 @@ void usb_kill_urb(struct urb *urb)
EXPORT_SYMBOL(usb_init_urb);
EXPORT_SYMBOL(usb_alloc_urb);
+EXPORT_SYMBOL(usb_alloc_iso_urb);
EXPORT_SYMBOL(usb_free_urb);
EXPORT_SYMBOL(usb_get_urb);
EXPORT_SYMBOL(usb_submit_urb);
diff -urp vanilla/drivers/usb/host/ohci-mem.c isotree/drivers/usb/host/ohci-mem.c
--- vanilla/drivers/usb/host/ohci-mem.c 2007-02-04 19:44:54.000000000 +0100
+++ isotree/drivers/usb/host/ohci-mem.c 2007-07-05 15:03:04.000000000 +0200
@@ -136,3 +136,16 @@ ed_free (struct ohci_hcd *hc, struct ed
dma_pool_free (hc->ed_cache, ed, ed->dma);
}
+static void ohci_free_urb(struct usb_hcd *hcd, struct urb *urb)
+{
+ kfree(urb);
+}
+
+static struct urb *ohci_alloc_urb(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep,
+ size_t alloc_length,
+ unsigned int num_iso_packets,
+ gfp_t mem_flags)
+{
+ return kmalloc(sizeof(struct urb), mem_flags);
+}
diff -urp vanilla/drivers/usb/host/ohci-pci.c isotree/drivers/usb/host/ohci-pci.c
--- vanilla/drivers/usb/host/ohci-pci.c 2007-07-04 14:14:45.000000000 +0200
+++ isotree/drivers/usb/host/ohci-pci.c 2007-07-05 14:59:59.000000000 +0200
@@ -282,6 +282,9 @@ static const struct hc_driver ohci_pci_h
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
+ .alloc_urb = ohci_alloc_urb,
+ .free_urb = ohci_free_urb,
+
/*
* scheduling support
*/
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel