Commit c5cd1f9d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[PATCH] USB: Remove interface/altsetting assumptions from usb-midi

This patch makes the usb-midi driver use usb_ifnum_to_if(), thereby
removing assumptions about which interface is stored in which array entry.
Similarly, it stores the bAlternateSetting value rather than the array
index for an altsetting entry.

Like the earlier patch for the audio driver, this also changes the driver
to use the in-memory rawdescriptor buffer rather than reading a
configuration descriptor from the device.  Unlike that earlier patch, this
time there's no question that the deallocation of the buffer is done
correctly.  (I suspect the audio driver just left out a call to kfree.)
parent e29852f8
......@@ -39,9 +39,6 @@
#include <linux/init.h>
#include <asm/semaphore.h>
/** This declaration is missing from linux/usb.h **/
extern int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size);
#include "usb-midi.h"
/* ------------------------------------------------------------------------- */
......@@ -1519,15 +1516,17 @@ static int on_bits( unsigned short v )
static int get_alt_setting( struct usb_device *d, int ifnum )
{
int alts, alt=0;
struct usb_interface *iface;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *ep;
int epin, epout;
int i;
alts = d->actconfig->interface[ifnum]->num_altsetting;
iface = usb_ifnum_to_if( d, ifnum );
alts = iface->num_altsetting;
for ( alt=0 ; alt<alts ; alt++ ) {
interface = &d->actconfig->interface[ifnum]->altsetting[alt];
interface = &iface->altsetting[alt];
epin = -1;
epout = -1;
......@@ -1542,7 +1541,7 @@ static int get_alt_setting( struct usb_device *d, int ifnum )
epout = i;
}
if ( epin >= 0 && epout >= 0 ) {
return alt;
return interface->desc.bAlternateSetting;
}
}
}
......@@ -1780,12 +1779,13 @@ static int alloc_usb_midi_device( struct usb_device *d, struct usb_midi_state *s
* Called by usb_midi_probe();
**/
static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s)
static int detect_yamaha_device( struct usb_device *d,
struct usb_interface *iface, unsigned int ifnum,
struct usb_midi_state *s)
{
struct usb_host_config *c = d->actconfig;
struct usb_host_interface *interface;
struct usb_midi_device *u;
unsigned char buf[USB_DT_CONFIG_SIZE], *buffer;
unsigned char *buffer;
int bufSize;
int i;
int alts=-1;
......@@ -1795,13 +1795,13 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc
return -EINVAL;
}
for ( i=0 ; i < c->interface[ifnum]->num_altsetting; i++ ) {
interface = c->interface[ifnum]->altsetting + i;
for ( i=0 ; i < iface->num_altsetting; i++ ) {
interface = iface->altsetting + i;
if ( interface->desc.bInterfaceClass != 255 ||
interface->desc.bInterfaceSubClass != 0 )
continue;
alts = i;
alts = interface->desc.bAlternateSetting;
}
if ( alts == -1 ) {
return -EINVAL;
......@@ -1810,30 +1810,11 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc
printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buf, USB_DT_CONFIG_SIZE );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get config (error=%d).\n", ret);
return -EINVAL;
}
if ( buf[1] != USB_DT_CONFIG || buf[0] < USB_DT_CONFIG_SIZE ) {
printk(KERN_INFO "usb-midi: config not as expected.\n");
return -EINVAL;
}
bufSize = buf[2] | buf[3]<<8;
buffer = (unsigned char *)kmalloc(sizeof(unsigned char)*bufSize, GFP_KERNEL);
if ( !buffer ) {
printk(KERN_INFO "usb-midi: Could not allocate memory.\n");
return -EINVAL;
}
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buffer, bufSize );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get full config (error=%d).\n", ret);
kfree(buffer);
return -EINVAL;
}
i = d->actconfig - d->config;
buffer = d->rawdescriptors[i];
bufSize = d->actconfig->desc.wTotalLength;
u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 1);
kfree(buffer);
if ( u == NULL ) {
return -EINVAL;
}
......@@ -1878,24 +1859,25 @@ static int detect_vendor_specific_device( struct usb_device *d, unsigned int ifn
* Returns 0 on success, negative on failure.
* Called by usb_midi_probe();
**/
static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct usb_midi_state *s)
static int detect_midi_subclass(struct usb_device *d,
struct usb_interface *iface, unsigned int ifnum,
struct usb_midi_state *s)
{
struct usb_host_config *c = d->actconfig;
struct usb_host_interface *interface;
struct usb_midi_device *u;
unsigned char buf[USB_DT_CONFIG_SIZE], *buffer;
unsigned char *buffer;
int bufSize;
int i;
int alts=-1;
int ret;
for ( i=0 ; i < c->interface[ifnum]->num_altsetting; i++ ) {
interface = c->interface[ifnum]->altsetting + i;
for ( i=0 ; i < iface->num_altsetting; i++ ) {
interface = iface->altsetting + i;
if ( interface->desc.bInterfaceClass != USB_CLASS_AUDIO ||
interface->desc.bInterfaceSubClass != USB_SUBCLASS_MIDISTREAMING )
continue;
alts = i;
alts = interface->desc.bAlternateSetting;
}
if ( alts == -1 ) {
return -EINVAL;
......@@ -1915,30 +1897,11 @@ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct
descriptor they modify or extend.
*/
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buf, USB_DT_CONFIG_SIZE );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get config (error=%d).\n", ret);
return -EINVAL;
}
if ( buf[1] != USB_DT_CONFIG || buf[0] < USB_DT_CONFIG_SIZE ) {
printk(KERN_INFO "usb-midi: config not as expected.\n");
return -EINVAL;
}
bufSize = buf[2] | buf[3]<<8;
buffer = (unsigned char *)kmalloc(sizeof(unsigned char)*bufSize, GFP_KERNEL);
if ( !buffer ) {
printk(KERN_INFO "usb-midi: Could not allocate memory.\n");
return -EINVAL;
}
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buffer, bufSize );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get full config (error=%d).\n", ret);
kfree(buffer);
return -EINVAL;
}
i = d->actconfig - d->config;
buffer = d->rawdescriptors[i];
bufSize = d->actconfig->desc.wTotalLength;
u = parse_descriptor( d, buffer, bufSize, ifnum, alts, 0);
kfree(buffer);
if ( u == NULL ) {
return -EINVAL;
}
......@@ -2002,7 +1965,7 @@ static int usb_midi_probe(struct usb_interface *intf,
{
struct usb_midi_state *s;
struct usb_device *dev = interface_to_usbdev(intf);
int ifnum = intf->altsetting->desc.bInterfaceNumber;
int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
s = (struct usb_midi_state *)kmalloc(sizeof(struct usb_midi_state), GFP_KERNEL);
if ( !s )
......@@ -2018,9 +1981,9 @@ static int usb_midi_probe(struct usb_interface *intf,
if (
detect_by_hand( dev, ifnum, s ) &&
detect_midi_subclass( dev, ifnum, s ) &&
detect_midi_subclass( dev, intf, ifnum, s ) &&
detect_vendor_specific_device( dev, ifnum, s ) &&
detect_yamaha_device( dev, ifnum, s) ) {
detect_yamaha_device( dev, intf, ifnum, s) ) {
kfree(s);
return -EIO;
}
......
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