Commit 40aafff3 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 4a07c099 cdbe443d
...@@ -59,6 +59,3 @@ obj-$(CONFIG_USB_TEST) += misc/ ...@@ -59,6 +59,3 @@ obj-$(CONFIG_USB_TEST) += misc/
obj-$(CONFIG_USB_TIGL) += misc/ obj-$(CONFIG_USB_TIGL) += misc/
obj-$(CONFIG_USB_USS720) += misc/ obj-$(CONFIG_USB_USS720) += misc/
obj-$(CONFIG_USB_NET2280) += gadget/
obj-$(CONFIG_USB_ZERO) += gadget/
obj-$(CONFIG_USB_ETH) += gadget/
...@@ -756,7 +756,7 @@ static int usb_hub_port_reset(struct usb_device *hub, int port, ...@@ -756,7 +756,7 @@ static int usb_hub_port_reset(struct usb_device *hub, int port,
return -1; return -1;
} }
void usb_hub_port_disable(struct usb_device *hub, int port) int usb_hub_port_disable(struct usb_device *hub, int port)
{ {
int ret; int ret;
...@@ -764,6 +764,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port) ...@@ -764,6 +764,8 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
if (ret) if (ret)
dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n", dev_err(hubdev(hub), "cannot disable port %d (err = %d)\n",
port + 1, ret); port + 1, ret);
return ret;
} }
/* USB 2.0 spec, 7.1.7.3 / fig 7-29: /* USB 2.0 spec, 7.1.7.3 / fig 7-29:
......
...@@ -731,6 +731,70 @@ static void usb_release_dev(struct device *dev) ...@@ -731,6 +731,70 @@ static void usb_release_dev(struct device *dev)
} }
static struct usb_device *match_device(struct usb_device *dev,
u16 vendor_id, u16 product_id)
{
struct usb_device *ret_dev = NULL;
int child;
dbg("looking at vendor %d, product %d",
dev->descriptor.idVendor,
dev->descriptor.idProduct);
/* see if this device matches */
if ((dev->descriptor.idVendor == vendor_id) &&
(dev->descriptor.idProduct == product_id)) {
dbg ("found the device!");
ret_dev = usb_get_dev(dev);
goto exit;
}
/* look through all of the children of this device */
for (child = 0; child < dev->maxchild; ++child) {
if (dev->children[child]) {
ret_dev = match_device(dev->children[child],
vendor_id, product_id);
if (ret_dev)
goto exit;
}
}
exit:
return ret_dev;
}
/**
* usb_find_device - find a specific usb device in the system
* @vendor_id: the vendor id of the device to find
* @product_id: the product id of the device to find
*
* Returns a pointer to a struct usb_device if such a specified usb
* device is present in the system currently. The usage count of the
* device will be incremented if a device is found. Make sure to call
* usb_put_dev() when the caller is finished with the device.
*
* If a device with the specified vendor and product id is not found,
* NULL is returned.
*/
struct usb_device *usb_find_device(u16 vendor_id, u16 product_id)
{
struct list_head *buslist;
struct usb_bus *bus;
struct usb_device *dev = NULL;
down(&usb_bus_list_lock);
for (buslist = usb_bus_list.next;
buslist != &usb_bus_list;
buslist = buslist->next) {
bus = container_of(buslist, struct usb_bus, bus_list);
dev = match_device(bus->root_hub, vendor_id, product_id);
if (dev)
goto exit;
}
exit:
up(&usb_bus_list_lock);
return dev;
}
/** /**
* usb_get_current_frame_number - return current bus frame number * usb_get_current_frame_number - return current bus frame number
* @dev: the device whose bus is being queried * @dev: the device whose bus is being queried
...@@ -1510,6 +1574,7 @@ EXPORT_SYMBOL(usb_disconnect); ...@@ -1510,6 +1574,7 @@ EXPORT_SYMBOL(usb_disconnect);
EXPORT_SYMBOL(__usb_get_extra_descriptor); EXPORT_SYMBOL(__usb_get_extra_descriptor);
EXPORT_SYMBOL(usb_find_device);
EXPORT_SYMBOL(usb_get_current_frame_number); EXPORT_SYMBOL(usb_get_current_frame_number);
EXPORT_SYMBOL (usb_buffer_alloc); EXPORT_SYMBOL (usb_buffer_alloc);
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
* *
* Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
* *
* Changelog:
* 30/05/2003 replaced lock/unlock kernel with up/down
* Daniele Bellucci bellucda@tiscali.it
* */ * */
#include <linux/module.h> #include <linux/module.h>
...@@ -75,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file) ...@@ -75,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file)
{ {
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
lock_kernel(); down(&(rio->lock));
if (rio->isopen || !rio->present) { if (rio->isopen || !rio->present) {
unlock_kernel(); up(&(rio->lock));
return -EBUSY; return -EBUSY;
} }
rio->isopen = 1; rio->isopen = 1;
init_waitqueue_head(&rio->wait_q); init_waitqueue_head(&rio->wait_q);
unlock_kernel(); up(&(rio->lock));
info("Rio opened."); info("Rio opened.");
...@@ -460,7 +463,6 @@ static int probe_rio(struct usb_interface *intf, ...@@ -460,7 +463,6 @@ static int probe_rio(struct usb_interface *intf,
return -ENOMEM; return -ENOMEM;
} }
rio->present = 1;
rio->rio_dev = dev; rio->rio_dev = dev;
if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
...@@ -481,6 +483,8 @@ static int probe_rio(struct usb_interface *intf, ...@@ -481,6 +483,8 @@ static int probe_rio(struct usb_interface *intf,
init_MUTEX(&(rio->lock)); init_MUTEX(&(rio->lock));
usb_set_intfdata (intf, rio); usb_set_intfdata (intf, rio);
rio->present = 1;
return 0; return 0;
} }
...@@ -525,7 +529,7 @@ static struct usb_driver rio_driver = { ...@@ -525,7 +529,7 @@ static struct usb_driver rio_driver = {
.id_table = rio_table, .id_table = rio_table,
}; };
int usb_rio_init(void) static int __init usb_rio_init(void)
{ {
if (usb_register(&rio_driver) < 0) if (usb_register(&rio_driver) < 0)
return -1; return -1;
...@@ -536,7 +540,7 @@ int usb_rio_init(void) ...@@ -536,7 +540,7 @@ int usb_rio_init(void)
} }
void usb_rio_cleanup(void) static void __exit usb_rio_cleanup(void)
{ {
struct rio_usb_data *rio = &rio_instance; struct rio_usb_data *rio = &rio_instance;
......
...@@ -351,6 +351,7 @@ config USB_SERIAL_KOBIL_SCT ...@@ -351,6 +351,7 @@ config USB_SERIAL_KOBIL_SCT
- USB TWIN - USB TWIN
- KAAN Standard Plus - KAAN Standard Plus
- KAAN SIM
- SecOVID Reader Plus - SecOVID Reader Plus
- B1 Professional - B1 Professional
- KAAN Professional - KAAN Professional
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
* Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
* (Adapter K), B1 Professional and KAAN Professional (Adapter B) * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
* *
* TODO: High baudrates * (28/05/2003) tw
* Add support for KAAN SIM
* *
* (12/09/2002) tw * (12/09/2002) tw
* Adapted to 2.5. * Adapted to 2.5.
...@@ -58,7 +59,7 @@ ...@@ -58,7 +59,7 @@
#include "usb-serial.h" #include "usb-serial.h"
/* Version Information */ /* Version Information */
#define DRIVER_VERSION "12/09/2002" #define DRIVER_VERSION "28/05/2003"
#define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com" #define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com"
#define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)" #define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)"
...@@ -66,6 +67,7 @@ ...@@ -66,6 +67,7 @@
#define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011 #define KOBIL_ADAPTER_B_PRODUCT_ID 0x2011
#define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012 #define KOBIL_ADAPTER_K_PRODUCT_ID 0x2012
#define KOBIL_USBTWIN_PRODUCT_ID 0x0078 #define KOBIL_USBTWIN_PRODUCT_ID 0x0078
#define KOBIL_KAAN_SIM_PRODUCT_ID 0x0081
#define KOBIL_TIMEOUT 500 #define KOBIL_TIMEOUT 500
#define KOBIL_BUF_LENGTH 300 #define KOBIL_BUF_LENGTH 300
...@@ -92,12 +94,22 @@ static struct usb_device_id id_table [] = { ...@@ -92,12 +94,22 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) }, { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) }, { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_K_PRODUCT_ID) },
{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) }, { USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_USBTWIN_PRODUCT_ID) },
{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_KAAN_SIM_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE (usb, id_table); MODULE_DEVICE_TABLE (usb, id_table);
static struct usb_driver kobil_driver = {
.owner = THIS_MODULE,
.name = "kobil",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
.id_table = id_table,
};
struct usb_serial_device_type kobil_device = { struct usb_serial_device_type kobil_device = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "KOBIL USB smart card terminal", .name = "KOBIL USB smart card terminal",
...@@ -161,6 +173,9 @@ static int kobil_startup (struct usb_serial *serial) ...@@ -161,6 +173,9 @@ static int kobil_startup (struct usb_serial *serial)
case KOBIL_USBTWIN_PRODUCT_ID: case KOBIL_USBTWIN_PRODUCT_ID:
printk(KERN_DEBUG "KOBIL USBTWIN detected\n"); printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
break; break;
case KOBIL_KAAN_SIM_PRODUCT_ID:
printk(KERN_DEBUG "KOBIL KAAN SIM detected\n");
break;
} }
usb_set_serial_port_data(serial->port, priv); usb_set_serial_port_data(serial->port, priv);
...@@ -353,7 +368,7 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) ...@@ -353,7 +368,7 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
struct usb_serial_port *port = (struct usb_serial_port *) purb->context; struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
struct tty_struct *tty; struct tty_struct *tty;
unsigned char *data = purb->transfer_buffer; unsigned char *data = purb->transfer_buffer;
char *dbg_data; // char *dbg_data;
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
...@@ -366,16 +381,18 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs) ...@@ -366,16 +381,18 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
if (purb->actual_length) { if (purb->actual_length) {
// BEGIN DEBUG // BEGIN DEBUG
dbg_data = (unsigned char *) kmalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL); /*
if (! dbg_data) { dbg_data = (unsigned char *) kmalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
return; if (! dbg_data) {
} return;
memset(dbg_data, 0, (3 * purb->actual_length + 10)); }
for (i = 0; i < purb->actual_length; i++) { memset(dbg_data, 0, (3 * purb->actual_length + 10));
sprintf(dbg_data +3*i, "%02X ", data[i]); for (i = 0; i < purb->actual_length; i++) {
} sprintf(dbg_data +3*i, "%02X ", data[i]);
dbg(" <-- %s", dbg_data ); }
kfree(dbg_data); dbg(" <-- %s", dbg_data );
kfree(dbg_data);
*/
// END DEBUG // END DEBUG
for (i = 0; i < purb->actual_length; ++i) { for (i = 0; i < purb->actual_length; ++i) {
...@@ -438,7 +455,7 @@ static int kobil_write (struct usb_serial_port *port, int from_user, ...@@ -438,7 +455,7 @@ static int kobil_write (struct usb_serial_port *port, int from_user,
priv->filled = priv->filled + count; priv->filled = priv->filled + count;
// only send complete block. TWIN and adapter K use the same protocol. // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol.
if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) { ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
...@@ -503,7 +520,7 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) ...@@ -503,7 +520,7 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file)
int transfer_buffer_length = 8; int transfer_buffer_length = 8;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) { if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
// This device doesn't support ioctl calls // This device doesn't support ioctl calls
return -EINVAL; return -EINVAL;
} }
...@@ -549,7 +566,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, ...@@ -549,7 +566,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file,
int transfer_buffer_length = 8; int transfer_buffer_length = 8;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) { if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
// This device doesn't support ioctl calls // This device doesn't support ioctl calls
return -EINVAL; return -EINVAL;
} }
...@@ -616,7 +633,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, ...@@ -616,7 +633,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
char *settings; char *settings;
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) { if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
// This device doesn't support ioctl calls // This device doesn't support ioctl calls
return 0; return 0;
} }
...@@ -727,6 +744,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, ...@@ -727,6 +744,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
static int __init kobil_init (void) static int __init kobil_init (void)
{ {
usb_serial_register (&kobil_device); usb_serial_register (&kobil_device);
usb_register (&kobil_driver);
info(DRIVER_VERSION " " DRIVER_AUTHOR); info(DRIVER_VERSION " " DRIVER_AUTHOR);
info(DRIVER_DESC); info(DRIVER_DESC);
...@@ -737,6 +755,7 @@ static int __init kobil_init (void) ...@@ -737,6 +755,7 @@ static int __init kobil_init (void)
static void __exit kobil_exit (void) static void __exit kobil_exit (void)
{ {
usb_deregister (&kobil_driver);
usb_serial_deregister (&kobil_device); usb_serial_deregister (&kobil_device);
} }
......
...@@ -670,7 +670,7 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us) ...@@ -670,7 +670,7 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us)
srb->result = SUCCESS; srb->result = SUCCESS;
} else { } else {
info->sense_key = UNIT_ATTENTION; info->sense_key = UNIT_ATTENTION;
srb->result = CHECK_CONDITION << 1; srb->result = SAM_STAT_CHECK_CONDITION;
} }
return rc; return rc;
} }
......
...@@ -399,7 +399,7 @@ freecom_init (struct us_data *us) ...@@ -399,7 +399,7 @@ freecom_init (struct us_data *us)
} }
} }
result = usb_control_msg(us->pusb_dev, us->recv_ctrl_pipe, result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ); 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ);
buffer[32] = '\0'; buffer[32] = '\0';
US_DEBUGP("String returned from FC init is: %s\n", buffer); US_DEBUGP("String returned from FC init is: %s\n", buffer);
...@@ -411,7 +411,7 @@ freecom_init (struct us_data *us) ...@@ -411,7 +411,7 @@ freecom_init (struct us_data *us)
*/ */
/* send reset */ /* send reset */
result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe, result = usb_stor_control_msg(us, us->send_ctrl_pipe,
0x4d, 0x40, 0x24d8, 0x0, NULL, 0x0, 3*HZ); 0x4d, 0x40, 0x24d8, 0x0, NULL, 0x0, 3*HZ);
US_DEBUGP("result from activate reset is %d\n", result); US_DEBUGP("result from activate reset is %d\n", result);
...@@ -419,7 +419,7 @@ freecom_init (struct us_data *us) ...@@ -419,7 +419,7 @@ freecom_init (struct us_data *us)
mdelay(250); mdelay(250);
/* clear reset */ /* clear reset */
result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe, result = usb_stor_control_msg(us, us->send_ctrl_pipe,
0x4d, 0x40, 0x24f8, 0x0, NULL, 0x0, 3*HZ); 0x4d, 0x40, 0x24f8, 0x0, NULL, 0x0, 3*HZ);
US_DEBUGP("result from clear reset is %d\n", result); US_DEBUGP("result from clear reset is %d\n", result);
......
...@@ -50,7 +50,7 @@ int usb_stor_euscsi_init(struct us_data *us) ...@@ -50,7 +50,7 @@ int usb_stor_euscsi_init(struct us_data *us)
int result; int result;
US_DEBUGP("Attempting to init eUSCSI bridge...\n"); US_DEBUGP("Attempting to init eUSCSI bridge...\n");
result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe, result = usb_stor_control_msg(us, us->send_ctrl_pipe,
0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR,
0x01, 0x0, &data, 0x1, 5*HZ); 0x01, 0x0, &data, 0x1, 5*HZ);
US_DEBUGP("-- result is %d\n", result); US_DEBUGP("-- result is %d\n", result);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/config.h> #include <linux/config.h>
#include "usb.h" #include "usb.h"
#include "transport.h"
/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
* mode */ * mode */
......
...@@ -558,7 +558,7 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -558,7 +558,7 @@ void isd200_invoke_transport( struct us_data *us,
case USB_STOR_TRANSPORT_GOOD: case USB_STOR_TRANSPORT_GOOD:
/* Indicate a good result */ /* Indicate a good result */
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
break; break;
case USB_STOR_TRANSPORT_FAILED: case USB_STOR_TRANSPORT_FAILED:
...@@ -598,11 +598,11 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -598,11 +598,11 @@ void isd200_invoke_transport( struct us_data *us,
} }
if (result == ISD200_GOOD) { if (result == ISD200_GOOD) {
isd200_build_sense(us, srb); isd200_build_sense(us, srb);
srb->result = CHECK_CONDITION << 1; srb->result = SAM_STAT_CHECK_CONDITION;
/* If things are really okay, then let's show that */ /* If things are really okay, then let's show that */
if ((srb->sense_buffer[2] & 0xf) == 0x0) if ((srb->sense_buffer[2] & 0xf) == 0x0)
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
} else } else
srb->result = DID_ERROR << 16; srb->result = DID_ERROR << 16;
} }
...@@ -611,7 +611,7 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -611,7 +611,7 @@ void isd200_invoke_transport( struct us_data *us,
* condition, show that in the result code * condition, show that in the result code
*/ */
if (transferStatus == USB_STOR_TRANSPORT_FAILED) if (transferStatus == USB_STOR_TRANSPORT_FAILED)
srb->result = CHECK_CONDITION << 1; srb->result = SAM_STAT_CHECK_CONDITION;
} }
#ifdef CONFIG_USB_STORAGE_DEBUG #ifdef CONFIG_USB_STORAGE_DEBUG
...@@ -1185,7 +1185,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1185,7 +1185,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
/* copy InquiryData */ /* copy InquiryData */
isd200_data_copy(srb, (char *) &info->InquiryData, srb->request_bufflen); isd200_data_copy(srb, (char *) &info->InquiryData, srb->request_bufflen);
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
break; break;
...@@ -1205,7 +1205,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1205,7 +1205,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb->request_bufflen = 0; srb->request_bufflen = 0;
} else { } else {
US_DEBUGP(" Media Status not supported, just report okay\n"); US_DEBUGP(" Media Status not supported, just report okay\n");
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
} }
break; break;
...@@ -1226,7 +1226,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1226,7 +1226,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb->request_bufflen = 0; srb->request_bufflen = 0;
} else { } else {
US_DEBUGP(" Media Status not supported, just report okay\n"); US_DEBUGP(" Media Status not supported, just report okay\n");
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
} }
break; break;
...@@ -1252,7 +1252,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1252,7 +1252,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb->request_bufflen = sizeof(struct read_capacity_data); srb->request_bufflen = sizeof(struct read_capacity_data);
isd200_data_copy(srb, (char *) &readCapacityData, srb->request_bufflen); isd200_data_copy(srb, (char *) &readCapacityData, srb->request_bufflen);
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
} }
break; break;
...@@ -1336,7 +1336,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1336,7 +1336,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb->request_bufflen = 0; srb->request_bufflen = 0;
} else { } else {
US_DEBUGP(" Not removeable media, just report okay\n"); US_DEBUGP(" Not removeable media, just report okay\n");
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
} }
break; break;
...@@ -1365,7 +1365,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, ...@@ -1365,7 +1365,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb->request_bufflen = 0; srb->request_bufflen = 0;
} else { } else {
US_DEBUGP(" Nothing to do, just report okay\n"); US_DEBUGP(" Nothing to do, just report okay\n");
srb->result = GOOD << 1; srb->result = SAM_STAT_GOOD;
sendToTransport = FALSE; sendToTransport = FALSE;
} }
break; break;
......
...@@ -611,7 +611,7 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us) ...@@ -611,7 +611,7 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
srb->result = SUCCESS; srb->result = SUCCESS;
} else { } else {
info->sense_key = UNIT_ATTENTION; info->sense_key = UNIT_ATTENTION;
srb->result = CHECK_CONDITION << 1; srb->result = SAM_STAT_CHECK_CONDITION;
} }
return rc; return rc;
} }
......
...@@ -137,8 +137,7 @@ void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) ...@@ -137,8 +137,7 @@ void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */ /* send the command to the transport layer */
usb_stor_invoke_transport(srb, us); usb_stor_invoke_transport(srb, us);
if (srb->result == GOOD << 1) { if (srb->result == SAM_STAT_GOOD) {
/* fix the INQUIRY data if necessary */ /* fix the INQUIRY data if necessary */
fix_inquiry_data(srb); fix_inquiry_data(srb);
} }
...@@ -210,7 +209,7 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) ...@@ -210,7 +209,7 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */ /* send the command to the transport layer */
usb_stor_invoke_transport(srb, us); usb_stor_invoke_transport(srb, us);
if (srb->result == GOOD << 1) { if (srb->result == SAM_STAT_GOOD) {
/* Fix the MODE_SENSE data if we translated the command */ /* Fix the MODE_SENSE data if we translated the command */
if (old_cmnd == MODE_SENSE) if (old_cmnd == MODE_SENSE)
...@@ -307,7 +306,7 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) ...@@ -307,7 +306,7 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */ /* send the command to the transport layer */
usb_stor_invoke_transport(srb, us); usb_stor_invoke_transport(srb, us);
if (srb->result == GOOD << 1) { if (srb->result == SAM_STAT_GOOD) {
/* Fix the MODE_SENSE data if we translated the command */ /* Fix the MODE_SENSE data if we translated the command */
if (old_cmnd == MODE_SENSE) if (old_cmnd == MODE_SENSE)
...@@ -376,7 +375,7 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) ...@@ -376,7 +375,7 @@ void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
/* send the command to the transport layer */ /* send the command to the transport layer */
usb_stor_invoke_transport(srb, us); usb_stor_invoke_transport(srb, us);
if (srb->result == GOOD << 1) { if (srb->result == SAM_STAT_GOOD) {
/* Fix the MODE_SENSE data if we translated the command */ /* Fix the MODE_SENSE data if we translated the command */
if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE)) if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE))
......
...@@ -219,7 +219,7 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb ) ...@@ -219,7 +219,7 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
int state = atomic_read(&us->sm_state); int state = atomic_read(&us->sm_state);
int result; int result;
US_DEBUGP("device_reset() called\n" ); US_DEBUGP("%s called\n", __FUNCTION__);
if (state != US_STATE_IDLE) { if (state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: " printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state); "invalid state %d\n", __FUNCTION__, state);
...@@ -245,39 +245,49 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb ) ...@@ -245,39 +245,49 @@ static int usb_storage_device_reset( Scsi_Cmnd *srb )
return result; return result;
} }
/* This resets the device port */ /* This resets the device's USB port. */
/* It refuses to work if there's more than one interface in /* It refuses to work if there's more than one interface in
this device, so that other users are not affected. */ * the device, so that other users are not affected. */
/* This is always called with scsi_lock(srb->host) held */ /* This is always called with scsi_lock(srb->host) held */
static int usb_storage_bus_reset( Scsi_Cmnd *srb ) static int usb_storage_bus_reset( Scsi_Cmnd *srb )
{ {
struct us_data *us; struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
int state = atomic_read(&us->sm_state);
int result; int result;
/* we use the usb_reset_device() function to handle this for us */ US_DEBUGP("%s called\n", __FUNCTION__);
US_DEBUGP("bus_reset() called\n"); if (state != US_STATE_IDLE) {
printk(KERN_ERR USB_STORAGE "Error in %s: "
"invalid state %d\n", __FUNCTION__, state);
return FAILED;
}
/* set the state and release the lock */
atomic_set(&us->sm_state, US_STATE_RESETTING);
scsi_unlock(srb->device->host); scsi_unlock(srb->device->host);
us = (struct us_data *)srb->device->host->hostdata[0];
/* The USB subsystem doesn't handle synchronisation between /* The USB subsystem doesn't handle synchronisation between
a device's several drivers. Therefore we reset only devices a device's several drivers. Therefore we reset only devices
with one interface which we of course own. with just one interface, which we of course own.
*/ */
//FIXME: needs locking against config changes //FIXME: needs locking against config changes
if ( us->pusb_dev->actconfig->desc.bNumInterfaces == 1) { if (us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
/* attempt to reset the port */
/* lock the device and attempt to reset the port */
down(&(us->dev_semaphore));
result = usb_reset_device(us->pusb_dev); result = usb_reset_device(us->pusb_dev);
up(&(us->dev_semaphore));
US_DEBUGP("usb_reset_device returns %d\n", result); US_DEBUGP("usb_reset_device returns %d\n", result);
} else { } else {
result = -EBUSY; result = -EBUSY;
US_DEBUGP("cannot reset a multiinterface device. failing to reset.\n"); US_DEBUGP("Refusing to reset a multi-interface device\n");
} }
US_DEBUGP("bus_reset() complete\n"); /* lock access to the state and clear it */
scsi_lock(srb->device->host); scsi_lock(srb->device->host);
atomic_set(&us->sm_state, US_STATE_IDLE);
return result < 0 ? FAILED : SUCCESS; return result < 0 ? FAILED : SUCCESS;
} }
......
This diff is collapsed.
...@@ -160,9 +160,9 @@ extern void usb_stor_stop_transport(struct us_data*); ...@@ -160,9 +160,9 @@ extern void usb_stor_stop_transport(struct us_data*);
extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index, u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size); void *data, u16 size, int timeout);
extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe);
extern int usb_stor_clear_halt(struct us_data*, unsigned int pipe);
extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
u8 request, u8 requesttype, u16 value, u16 index, u8 request, u8 requesttype, u16 value, u16 index,
void *data, u16 size); void *data, u16 size);
......
...@@ -374,7 +374,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -374,7 +374,7 @@ static int usb_stor_control_thread(void * __us)
memcpy(us->srb->sense_buffer, memcpy(us->srb->sense_buffer,
usb_stor_sense_invalidCDB, usb_stor_sense_invalidCDB,
sizeof(usb_stor_sense_invalidCDB)); sizeof(usb_stor_sense_invalidCDB));
us->srb->result = CHECK_CONDITION << 1; us->srb->result = SAM_STAT_CHECK_CONDITION;
} }
/* Handle those devices which need us to fake /* Handle those devices which need us to fake
...@@ -387,7 +387,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -387,7 +387,7 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP("Faking INQUIRY command\n"); US_DEBUGP("Faking INQUIRY command\n");
fill_inquiry_response(us, data_ptr, 36); fill_inquiry_response(us, data_ptr, 36);
us->srb->result = GOOD << 1; us->srb->result = SAM_STAT_GOOD;
} }
/* we've got a command, let's do it! */ /* we've got a command, let's do it! */
...@@ -412,9 +412,11 @@ static int usb_stor_control_thread(void * __us) ...@@ -412,9 +412,11 @@ static int usb_stor_control_thread(void * __us)
US_DEBUGP("scsi command aborted\n"); US_DEBUGP("scsi command aborted\n");
} }
/* in case an abort request was received after the command /* If an abort request was received we need to signal that
* completed, we must use a separate test to see whether * the abort has finished. The proper test for this is
* we need to signal that the abort has finished */ * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
* because an abort request might be received after all the
* USB processing was complete. */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) if (atomic_read(&us->sm_state) == US_STATE_ABORTING)
complete(&(us->notify)); complete(&(us->notify));
...@@ -715,7 +717,6 @@ static int storage_probe(struct usb_interface *intf, ...@@ -715,7 +717,6 @@ static int storage_probe(struct usb_interface *intf,
us->transport_name = "Bulk"; us->transport_name = "Bulk";
us->transport = usb_stor_Bulk_transport; us->transport = usb_stor_Bulk_transport;
us->transport_reset = usb_stor_Bulk_reset; us->transport_reset = usb_stor_Bulk_reset;
us->max_lun = usb_stor_Bulk_max_lun(us);
break; break;
#ifdef CONFIG_USB_STORAGE_HP8200e #ifdef CONFIG_USB_STORAGE_HP8200e
...@@ -842,6 +843,10 @@ static int storage_probe(struct usb_interface *intf, ...@@ -842,6 +843,10 @@ static int storage_probe(struct usb_interface *intf,
if (usb_stor_allocate_urbs(us)) if (usb_stor_allocate_urbs(us))
goto BadDevice; goto BadDevice;
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == US_PR_BULK)
us->max_lun = usb_stor_Bulk_max_lun(us);
/* /*
* Since this is a new device, we need to generate a scsi * Since this is a new device, we need to generate a scsi
* host definition, and register with the higher SCSI layers * host definition, and register with the higher SCSI layers
......
...@@ -82,7 +82,7 @@ struct us_unusual_dev { ...@@ -82,7 +82,7 @@ struct us_unusual_dev {
#define US_FLIDX_SG_ACTIVE 19 /* 0x00080000 current_sg is in use */ #define US_FLIDX_SG_ACTIVE 19 /* 0x00080000 current_sg is in use */
#define US_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */ #define US_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */
#define US_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */ #define US_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */
#define DONT_SUBMIT ((1UL << US_FLIDX_ABORTING) || \ #define DONT_SUBMIT ((1UL << US_FLIDX_ABORTING) | \
(1UL << US_FLIDX_DISCONNECTING)) (1UL << US_FLIDX_DISCONNECTING))
......
...@@ -278,6 +278,8 @@ extern void usb_put_dev(struct usb_device *dev); ...@@ -278,6 +278,8 @@ extern void usb_put_dev(struct usb_device *dev);
/* mostly for devices emulating SCSI over USB */ /* mostly for devices emulating SCSI over USB */
extern int usb_reset_device(struct usb_device *dev); extern int usb_reset_device(struct usb_device *dev);
extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
/* for drivers using iso endpoints */ /* for drivers using iso endpoints */
extern int usb_get_current_frame_number (struct usb_device *usb_dev); extern int usb_get_current_frame_number (struct usb_device *usb_dev);
......
...@@ -33,7 +33,7 @@ config SECURITY_CAPABILITIES ...@@ -33,7 +33,7 @@ config SECURITY_CAPABILITIES
config SECURITY_ROOTPLUG config SECURITY_ROOTPLUG
tristate "Root Plug Support" tristate "Root Plug Support"
depends on SECURITY!=n depends on USB && SECURITY!=n
help help
This is a sample LSM module that should only be used as such. This is a sample LSM module that should only be used as such.
It prevents any programs running with egid == 0 if a specific It prevents any programs running with egid == 0 if a specific
......
...@@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Debug enabled or not"); ...@@ -54,7 +54,7 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
#define MY_NAME "root_plug" #define MY_NAME "root_plug"
#endif #endif
#define dbg(fmt, arg...) \ #define root_dbg(fmt, arg...) \
do { \ do { \
if (debug) \ if (debug) \
printk(KERN_DEBUG "%s: %s: " fmt , \ printk(KERN_DEBUG "%s: %s: " fmt , \
...@@ -62,70 +62,21 @@ MODULE_PARM_DESC(debug, "Debug enabled or not"); ...@@ -62,70 +62,21 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
## arg); \ ## arg); \
} while (0) } while (0)
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
static int match_device (struct usb_device *dev)
{
int retval = -ENODEV;
int child;
dbg ("looking at vendor %d, product %d\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct);
/* see if this device matches */
if ((dev->descriptor.idVendor == vendor_id) &&
(dev->descriptor.idProduct == product_id)) {
dbg ("found the device!\n");
retval = 0;
goto exit;
}
/* look through all of the children of this device */
for (child = 0; child < dev->maxchild; ++child) {
if (dev->children[child]) {
retval = match_device (dev->children[child]);
if (retval == 0)
goto exit;
}
}
exit:
return retval;
}
static int find_usb_device (void)
{
struct list_head *buslist;
struct usb_bus *bus;
int retval = -ENODEV;
down (&usb_bus_list_lock);
for (buslist = usb_bus_list.next;
buslist != &usb_bus_list;
buslist = buslist->next) {
bus = container_of (buslist, struct usb_bus, bus_list);
retval = match_device(bus->root_hub);
if (retval == 0)
goto exit;
}
exit:
up (&usb_bus_list_lock);
return retval;
}
static int rootplug_bprm_check_security (struct linux_binprm *bprm) static int rootplug_bprm_check_security (struct linux_binprm *bprm)
{ {
dbg ("file %s, e_uid = %d, e_gid = %d\n", struct usb_device *dev;
bprm->filename, bprm->e_uid, bprm->e_gid);
root_dbg("file %s, e_uid = %d, e_gid = %d\n",
bprm->filename, bprm->e_uid, bprm->e_gid);
if (bprm->e_gid == 0) { if (bprm->e_gid == 0) {
if (find_usb_device() != 0) { dev = usb_find_device(vendor_id, product_id);
dbg ("e_gid = 0, and device not found, " if (!dev) {
"task not allowed to run...\n"); root_dbg("e_gid = 0, and device not found, "
"task not allowed to run...\n");
return -EPERM; return -EPERM;
} }
usb_put_dev(dev);
} }
return 0; return 0;
......
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