/* USB related parts */
-static void *
-hpusbscsi_usb_probe (struct usb_device *dev, unsigned int interface,
+static int
+hpusbscsi_usb_probe (struct usb_interface *intf,
const struct usb_device_id *id)
{
struct hpusbscsi *new;
+ struct usb_device *dev = interface_to_usbdev (intf);
struct usb_interface_descriptor *altsetting =
- &(dev->actconfig->interface[interface].altsetting[0]);
+ &(intf->altsetting[0]);
int i, result;
if (altsetting->bNumEndpoints != 3) {
printk (KERN_ERR "Wrong number of endpoints\n");
- return NULL;
+ return -ENODEV;
}
/* descriptor allocation */
(struct hpusbscsi *) kmalloc (sizeof (struct hpusbscsi),
GFP_KERNEL);
if (new == NULL)
- return NULL;
+ return -ENOMEM;
DEBUG ("Allocated memory\n");
memset (new, 0, sizeof (struct hpusbscsi));
new->dataurb = usb_alloc_urb(0, GFP_KERNEL);
if (!new->dataurb) {
kfree (new);
- return NULL;
+ return -ENOMEM;
}
new->controlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!new->controlurb) {
usb_free_urb (new->dataurb);
kfree (new);
- return NULL;
+ return -ENOMEM;
}
new->dev = dev;
init_waitqueue_head (&new->pending);
/* adding to list for module unload */
list_add (&hpusbscsi_devices, &new->lh);
- return new;
+ dev_set_drvdata(&intf->dev, new);
+ return 0;
err_out:
usb_free_urb (new->controlurb);
usb_free_urb (new->dataurb);
kfree (new);
- return NULL;
+ return -ENODEV;
}
static void
-hpusbscsi_usb_disconnect (struct usb_device *dev, void *ptr)
+hpusbscsi_usb_disconnect (struct usb_interface *intf)
{
- usb_unlink_urb((((struct hpusbscsi *) ptr)->controlurb));
- ((struct hpusbscsi *) ptr)->dev = NULL;
+ struct hpusbscsi *desc = dev_get_drvdata(&intf->dev);
+
+ dev_set_drvdata(&intf->dev, NULL);
+ if (desc)
+ usb_unlink_urb(desc->controlurb);
}
static struct usb_device_id hpusbscsi_usb_ids[] = {
/*
* Callback to search the Mustek MDC800 on the USB Bus
*/
-static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
+static int mdc800_usb_probe (struct usb_interface *intf,
const struct usb_device_id *id)
{
int i,j;
struct usb_interface_descriptor *intf_desc;
+ struct usb_device *dev = interface_to_usbdev (intf);
int irq_interval=0;
int retval;
if (mdc800->dev != 0)
{
warn ("only one Mustek MDC800 is supported.");
- return 0;
+ return -ENODEV;
}
if (dev->descriptor.bNumConfigurations != 1)
{
err ("probe fails -> wrong Number of Configuration");
- return 0;
+ return -ENODEV;
}
- intf_desc=&dev->actconfig->interface[ifnum].altsetting[0];
+ intf_desc = &intf->altsetting[0];
if (
( intf_desc->bInterfaceClass != 0xff )
)
{
err ("probe fails -> wrong Interface");
- return 0;
+ return -ENODEV;
}
/* Check the Endpoints */
if (mdc800->endpoint[i] == -1)
{
err ("probe fails -> Wrong Endpoints.");
- return 0;
+ return -ENODEV;
}
}
- usb_driver_claim_interface (&mdc800_usb_driver, &dev->actconfig->interface[ifnum], mdc800);
- if (usb_set_interface (dev, ifnum, 0) < 0)
+ usb_driver_claim_interface (&mdc800_usb_driver, intf, mdc800);
+ if (usb_set_interface (dev, intf_desc->bInterfaceNumber, 0) < 0)
{
err ("MDC800 Configuration fails.");
- return 0;
+ return -ENODEV;
}
info ("Found Mustek MDC800 on USB.");
retval = usb_register_dev (&mdc800_device_ops, MDC800_DEVICE_MINOR_BASE, 1, &mdc800->minor);
if (retval && (retval != -ENODEV)) {
err ("Not able to get a minor for this device.");
- return 0;
+ return -ENODEV;
}
mdc800->dev=dev;
up (&mdc800->io_lock);
- return mdc800;
+ dev_set_drvdata(&intf->dev, mdc800);
+ return 0;
}
/*
* Disconnect USB device (maybe the MDC800)
*/
-static void mdc800_usb_disconnect (struct usb_device *dev,void* ptr)
+static void mdc800_usb_disconnect (struct usb_interface *intf)
{
- struct mdc800_data* mdc800=(struct mdc800_data*) ptr;
+ struct mdc800_data* mdc800 = dev_get_drvdata(&intf->dev);
dbg ("(mdc800_usb_disconnect) called");
- if (mdc800->state == NOT_CONNECTED)
- return;
-
- usb_deregister_dev (1, mdc800->minor);
+ if (mdc800) {
+ if (mdc800->state == NOT_CONNECTED)
+ return;
- mdc800->state=NOT_CONNECTED;
+ usb_deregister_dev (1, mdc800->minor);
- usb_unlink_urb (mdc800->irq_urb);
- usb_unlink_urb (mdc800->write_urb);
- usb_unlink_urb (mdc800->download_urb);
+ mdc800->state=NOT_CONNECTED;
- usb_driver_release_interface (&mdc800_usb_driver, &dev->actconfig->interface[1]);
+ usb_unlink_urb (mdc800->irq_urb);
+ usb_unlink_urb (mdc800->write_urb);
+ usb_unlink_urb (mdc800->download_urb);
- mdc800->dev=0;
+ usb_driver_release_interface (&mdc800_usb_driver, intf);
+
+ mdc800->dev=0;
+ dev_set_drvdata(&intf->dev, NULL);
+ }
info ("Mustek MDC800 disconnected from USB.");
}
/* USB layer driver interface */
-static void *mts_usb_probe(struct usb_device *dev, unsigned int interface,
+static int mts_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id);
-static void mts_usb_disconnect(struct usb_device *dev, void *ptr);
+static void mts_usb_disconnect(struct usb_interface *intf);
static struct usb_device_id mts_usb_ids [];
/* USB layer driver interface implementation */
-static void mts_usb_disconnect (struct usb_device *dev, void *ptr)
+static void mts_usb_disconnect (struct usb_interface *intf)
{
- struct mts_desc* to_remove = (struct mts_desc*)ptr;
+ struct mts_desc* to_remove = dev_get_drvdata(&intf->dev);
MTS_DEBUG_GOT_HERE();
- /* leave the list - lock it */
- down(&mts_list_semaphore);
+ dev_set_drvdata(&intf->dev, NULL);
+ if (to_remove) {
+ /* leave the list - lock it */
+ down(&mts_list_semaphore);
- mts_remove_nolock(to_remove);
+ mts_remove_nolock(to_remove);
- up(&mts_list_semaphore);
+ up(&mts_list_semaphore);
+ }
}
struct vendor_product
MODULE_DEVICE_TABLE (usb, mts_usb_ids);
-static void * mts_usb_probe (struct usb_device *dev, unsigned int interface,
- const struct usb_device_id *id)
+static int mts_usb_probe (struct usb_interface *intf,
+ const struct usb_device_id *id)
{
int i;
int result;
struct mts_desc * new_desc;
struct vendor_product const* p;
+ struct usb_device *dev = interface_to_usbdev (intf);
/* the altsettting 0 on the interface we're probing */
struct usb_interface_descriptor *altsetting;
p->name );
/* the altsettting 0 on the interface we're probing */
- altsetting =
- &(dev->actconfig->interface[interface].altsetting[0]);
+ altsetting = &(intf->altsetting[0]);
/* Check if the config is sane */
if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) {
MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
(int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints );
- return NULL;
+ return -ENODEV;
}
for( i = 0; i < altsetting->bNumEndpoints; i++ ) {
else {
if ( ep_out != -1 ) {
MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
- return NULL;
+ return -ENODEV;
}
ep_out = altsetting->endpoint[i].bEndpointAddress &
if ( ep_out == -1 ) {
MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
- return NULL;
+ return -ENODEV;
}
default:
MTS_DEBUG( "unknown error %d from usb_set_interface\n",
(int)result );
- return NULL;
+ return -ENODEV;
}
if (new_desc == NULL)
{
MTS_ERROR("couldn't allocate scanner desc, bailing out!\n");
- return NULL;
+ return -ENOMEM;
}
memset( new_desc, 0, sizeof(*new_desc) );
new_desc->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!new_desc->urb) {
kfree(new_desc);
- return NULL;
+ return -ENOMEM;
}
/* initialising that descriptor */
new_desc->usb_dev = dev;
- new_desc->interface = interface;
init_MUTEX(&new_desc->lock);
/* FIXME: need more cleanup? */
kfree( new_desc );
- return NULL;
+ return -ENOMEM;
}
MTS_DEBUG_GOT_HERE();
MTS_DEBUG("completed probe and exiting happily\n");
- return (void *)new_desc;
+ dev_set_drvdata(&intf->dev, new_desc);
+ return 0;
}
struct usb_device *usb_dev;
- int interface;
-
/* Endpoint addresses */
u8 ep_out;
u8 ep_response;
.release = close_scanner,
};
-static void *
-probe_scanner(struct usb_device *dev, unsigned int ifnum,
+static int
+probe_scanner(struct usb_interface *intf,
const struct usb_device_id *id)
{
+ struct usb_device *dev = interface_to_usbdev (intf);
struct scn_usb_data *scn;
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
valid_device = 1;
}
- if (!valid_device)
- return NULL; /* We didn't find anything pleasing */
+ if (!valid_device)
+ return -ENODEV; /* We didn't find anything pleasing */
/*
* After this point we can be a little noisy about what we are trying to
if (dev->descriptor.bNumConfigurations != 1) {
info("probe_scanner: Only one device configuration is supported.");
- return NULL;
+ return -ENODEV;
}
if (dev->config[0].bNumInterfaces != 1) {
info("probe_scanner: Only one device interface is supported.");
- return NULL;
+ return -ENODEV;
}
- interface = dev->config[0].interface[ifnum].altsetting;
- endpoint = interface[ifnum].endpoint;
+ interface = intf->altsetting;
+ endpoint = interface->endpoint;
/*
* Start checking for two bulk endpoints OR two bulk endpoints *and* one
if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) {
info("probe_scanner: Only two or three endpoints supported.");
- return NULL;
+ return -ENODEV;
}
ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0;
continue;
}
info("probe_scanner: Undetected endpoint -- consult Documentation/usb/scanner.txt.");
- return NULL; /* Shouldn't ever get here unless we have something weird */
+ return -EIO; /* Shouldn't ever get here unless we have something weird */
}
case 2:
if (!have_bulk_in || !have_bulk_out) {
info("probe_scanner: Two bulk endpoints required.");
- return NULL;
+ return -EIO;
}
break;
case 3:
if (!have_bulk_in || !have_bulk_out || !have_intr) {
info("probe_scanner: Two bulk endpoints and one interrupt endpoint required.");
- return NULL;
+ return -EIO;
}
break;
default:
info("probe_scanner: Endpoint determination failed -- consult Documentation/usb/scanner.txt");
- return NULL;
+ return -EIO;
}
if (retval) {
err ("Not able to get a minor for this device.");
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
/* Check to make sure that the last slot isn't already taken */
if (p_scn_table[scn_minor]) {
err("probe_scanner: No more minor devices remaining.");
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
dbg("probe_scanner: Allocated minor:%d", scn_minor);
if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) {
err("probe_scanner: Out of memory.");
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
memset (scn, 0, sizeof(struct scn_usb_data));
if (!scn->scn_irq) {
kfree(scn);
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
init_MUTEX(&(scn->sem)); /* Initializes to unlocked */
err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor);
kfree(scn);
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
}
err("probe_scanner(%d): Not enough memory for the output buffer.", scn_minor);
kfree(scn);
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
dbg("probe_scanner(%d): obuf address:%p", scn_minor, scn->obuf);
kfree(scn->obuf);
kfree(scn);
up(&scn_mutex);
- return NULL;
+ return -ENOMEM;
}
dbg("probe_scanner(%d): ibuf address:%p", scn_minor, scn->ibuf);
up(&scn_mutex);
- return scn;
+ dev_set_drvdata(&intf->dev, scn);
+ return 0;
}
static void
-disconnect_scanner(struct usb_device *dev, void *ptr)
+disconnect_scanner(struct usb_interface *intf)
{
- struct scn_usb_data *scn = (struct scn_usb_data *) ptr;
+ struct scn_usb_data *scn = dev_get_drvdata(&intf->dev);
- down (&scn_mutex);
- down (&(scn->sem));
+ dev_set_drvdata(&intf->dev, NULL);
+ if (scn) {
+ down (&scn_mutex);
+ down (&(scn->sem));
- if(scn->intr_ep) {
- dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
- usb_unlink_urb(scn->scn_irq);
+ if(scn->intr_ep) {
+ dbg("disconnect_scanner(%d): Unlinking IRQ URB", scn->scn_minor);
+ usb_unlink_urb(scn->scn_irq);
+ }
+ usb_driver_release_interface(&scanner_driver,
+ &scn->scn_dev->actconfig->interface[scn->ifnum]);
+
+ kfree(scn->ibuf);
+ kfree(scn->obuf);
+
+ dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
+ devfs_unregister(scn->devfs);
+ usb_deregister_dev(1, scn->scn_minor);
+ p_scn_table[scn->scn_minor] = NULL;
+ usb_free_urb(scn->scn_irq);
+ up (&(scn->sem));
+ kfree (scn);
+ up (&scn_mutex);
}
- usb_driver_release_interface(&scanner_driver,
- &scn->scn_dev->actconfig->interface[scn->ifnum]);
-
- kfree(scn->ibuf);
- kfree(scn->obuf);
-
- dbg("disconnect_scanner: De-allocating minor:%d", scn->scn_minor);
- devfs_unregister(scn->devfs);
- usb_deregister_dev(1, scn->scn_minor);
- p_scn_table[scn->scn_minor] = NULL;
- usb_free_urb(scn->scn_irq);
- up (&(scn->sem));
- kfree (scn);
- up (&scn_mutex);
}
+/* we want to look at all devices, as the vendor/product id can change
+ * depending on the command line argument */
+static struct usb_device_id ids[] = {
+ {.driver_info = 42},
+ {}
+};
+
static struct
usb_driver scanner_driver = {
.name = "usbscanner",
.probe = probe_scanner,
.disconnect = disconnect_scanner,
- .id_table = NULL, /* This would be scanner_device_ids, but we
- need to check every USB device, in case
- we match a user defined vendor/product ID. */
+ .id_table = ids,
};
void __exit