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

Reply via email to