From ebb3770c01a8afd049e3e91b0a026dcdfcb2da9f Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 21 May 2008 17:06:26 -0600 Subject: USB: FTDI_SIO : Add support for Matrix Orbital PID Range This patch adds support for the range of PIDs that have been allocated for FTDI based devices at Matrix Orbital. A small number of units have been shipped early 2008 with a faulty USB Descriptor. Products that may have this issue have been marked with the existing quirk to work around the problem. Signed-off-by: R. Molenkamp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 264 ++++++++++++++++++++++++++++++++++++++++- drivers/usb/serial/ftdi_sio.h | 267 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 525 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3cee6feac174..5234e7a3bd2c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -174,8 +174,270 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, - { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID), .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) }, + { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index a72f2c81d664..06e0ecabb3eb 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -114,11 +114,268 @@ #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ /* - * The following are the values for the Matrix Orbital VK204-25-USB - * display, which use the FT232RL. - */ -#define MTXORB_VK_VID 0x1b3d -#define MTXORB_VK_PID 0x0158 + * The following are the values for the Matrix Orbital FTDI Range + * Anything in this range will use an FT232RL. + */ +#define MTXORB_VID 0x1B3D +#define MTXORB_FTDI_RANGE_0100_PID 0x0100 +#define MTXORB_FTDI_RANGE_0101_PID 0x0101 +#define MTXORB_FTDI_RANGE_0102_PID 0x0102 +#define MTXORB_FTDI_RANGE_0103_PID 0x0103 +#define MTXORB_FTDI_RANGE_0104_PID 0x0104 +#define MTXORB_FTDI_RANGE_0105_PID 0x0105 +#define MTXORB_FTDI_RANGE_0106_PID 0x0106 +#define MTXORB_FTDI_RANGE_0107_PID 0x0107 +#define MTXORB_FTDI_RANGE_0108_PID 0x0108 +#define MTXORB_FTDI_RANGE_0109_PID 0x0109 +#define MTXORB_FTDI_RANGE_010A_PID 0x010A +#define MTXORB_FTDI_RANGE_010B_PID 0x010B +#define MTXORB_FTDI_RANGE_010C_PID 0x010C +#define MTXORB_FTDI_RANGE_010D_PID 0x010D +#define MTXORB_FTDI_RANGE_010E_PID 0x010E +#define MTXORB_FTDI_RANGE_010F_PID 0x010F +#define MTXORB_FTDI_RANGE_0110_PID 0x0110 +#define MTXORB_FTDI_RANGE_0111_PID 0x0111 +#define MTXORB_FTDI_RANGE_0112_PID 0x0112 +#define MTXORB_FTDI_RANGE_0113_PID 0x0113 +#define MTXORB_FTDI_RANGE_0114_PID 0x0114 +#define MTXORB_FTDI_RANGE_0115_PID 0x0115 +#define MTXORB_FTDI_RANGE_0116_PID 0x0116 +#define MTXORB_FTDI_RANGE_0117_PID 0x0117 +#define MTXORB_FTDI_RANGE_0118_PID 0x0118 +#define MTXORB_FTDI_RANGE_0119_PID 0x0119 +#define MTXORB_FTDI_RANGE_011A_PID 0x011A +#define MTXORB_FTDI_RANGE_011B_PID 0x011B +#define MTXORB_FTDI_RANGE_011C_PID 0x011C +#define MTXORB_FTDI_RANGE_011D_PID 0x011D +#define MTXORB_FTDI_RANGE_011E_PID 0x011E +#define MTXORB_FTDI_RANGE_011F_PID 0x011F +#define MTXORB_FTDI_RANGE_0120_PID 0x0120 +#define MTXORB_FTDI_RANGE_0121_PID 0x0121 +#define MTXORB_FTDI_RANGE_0122_PID 0x0122 +#define MTXORB_FTDI_RANGE_0123_PID 0x0123 +#define MTXORB_FTDI_RANGE_0124_PID 0x0124 +#define MTXORB_FTDI_RANGE_0125_PID 0x0125 +#define MTXORB_FTDI_RANGE_0126_PID 0x0126 +#define MTXORB_FTDI_RANGE_0127_PID 0x0127 +#define MTXORB_FTDI_RANGE_0128_PID 0x0128 +#define MTXORB_FTDI_RANGE_0129_PID 0x0129 +#define MTXORB_FTDI_RANGE_012A_PID 0x012A +#define MTXORB_FTDI_RANGE_012B_PID 0x012B +#define MTXORB_FTDI_RANGE_012C_PID 0x012C +#define MTXORB_FTDI_RANGE_012D_PID 0x012D +#define MTXORB_FTDI_RANGE_012E_PID 0x012E +#define MTXORB_FTDI_RANGE_012F_PID 0x012F +#define MTXORB_FTDI_RANGE_0130_PID 0x0130 +#define MTXORB_FTDI_RANGE_0131_PID 0x0131 +#define MTXORB_FTDI_RANGE_0132_PID 0x0132 +#define MTXORB_FTDI_RANGE_0133_PID 0x0133 +#define MTXORB_FTDI_RANGE_0134_PID 0x0134 +#define MTXORB_FTDI_RANGE_0135_PID 0x0135 +#define MTXORB_FTDI_RANGE_0136_PID 0x0136 +#define MTXORB_FTDI_RANGE_0137_PID 0x0137 +#define MTXORB_FTDI_RANGE_0138_PID 0x0138 +#define MTXORB_FTDI_RANGE_0139_PID 0x0139 +#define MTXORB_FTDI_RANGE_013A_PID 0x013A +#define MTXORB_FTDI_RANGE_013B_PID 0x013B +#define MTXORB_FTDI_RANGE_013C_PID 0x013C +#define MTXORB_FTDI_RANGE_013D_PID 0x013D +#define MTXORB_FTDI_RANGE_013E_PID 0x013E +#define MTXORB_FTDI_RANGE_013F_PID 0x013F +#define MTXORB_FTDI_RANGE_0140_PID 0x0140 +#define MTXORB_FTDI_RANGE_0141_PID 0x0141 +#define MTXORB_FTDI_RANGE_0142_PID 0x0142 +#define MTXORB_FTDI_RANGE_0143_PID 0x0143 +#define MTXORB_FTDI_RANGE_0144_PID 0x0144 +#define MTXORB_FTDI_RANGE_0145_PID 0x0145 +#define MTXORB_FTDI_RANGE_0146_PID 0x0146 +#define MTXORB_FTDI_RANGE_0147_PID 0x0147 +#define MTXORB_FTDI_RANGE_0148_PID 0x0148 +#define MTXORB_FTDI_RANGE_0149_PID 0x0149 +#define MTXORB_FTDI_RANGE_014A_PID 0x014A +#define MTXORB_FTDI_RANGE_014B_PID 0x014B +#define MTXORB_FTDI_RANGE_014C_PID 0x014C +#define MTXORB_FTDI_RANGE_014D_PID 0x014D +#define MTXORB_FTDI_RANGE_014E_PID 0x014E +#define MTXORB_FTDI_RANGE_014F_PID 0x014F +#define MTXORB_FTDI_RANGE_0150_PID 0x0150 +#define MTXORB_FTDI_RANGE_0151_PID 0x0151 +#define MTXORB_FTDI_RANGE_0152_PID 0x0152 +#define MTXORB_FTDI_RANGE_0153_PID 0x0153 +#define MTXORB_FTDI_RANGE_0154_PID 0x0154 +#define MTXORB_FTDI_RANGE_0155_PID 0x0155 +#define MTXORB_FTDI_RANGE_0156_PID 0x0156 +#define MTXORB_FTDI_RANGE_0157_PID 0x0157 +#define MTXORB_FTDI_RANGE_0158_PID 0x0158 +#define MTXORB_FTDI_RANGE_0159_PID 0x0159 +#define MTXORB_FTDI_RANGE_015A_PID 0x015A +#define MTXORB_FTDI_RANGE_015B_PID 0x015B +#define MTXORB_FTDI_RANGE_015C_PID 0x015C +#define MTXORB_FTDI_RANGE_015D_PID 0x015D +#define MTXORB_FTDI_RANGE_015E_PID 0x015E +#define MTXORB_FTDI_RANGE_015F_PID 0x015F +#define MTXORB_FTDI_RANGE_0160_PID 0x0160 +#define MTXORB_FTDI_RANGE_0161_PID 0x0161 +#define MTXORB_FTDI_RANGE_0162_PID 0x0162 +#define MTXORB_FTDI_RANGE_0163_PID 0x0163 +#define MTXORB_FTDI_RANGE_0164_PID 0x0164 +#define MTXORB_FTDI_RANGE_0165_PID 0x0165 +#define MTXORB_FTDI_RANGE_0166_PID 0x0166 +#define MTXORB_FTDI_RANGE_0167_PID 0x0167 +#define MTXORB_FTDI_RANGE_0168_PID 0x0168 +#define MTXORB_FTDI_RANGE_0169_PID 0x0169 +#define MTXORB_FTDI_RANGE_016A_PID 0x016A +#define MTXORB_FTDI_RANGE_016B_PID 0x016B +#define MTXORB_FTDI_RANGE_016C_PID 0x016C +#define MTXORB_FTDI_RANGE_016D_PID 0x016D +#define MTXORB_FTDI_RANGE_016E_PID 0x016E +#define MTXORB_FTDI_RANGE_016F_PID 0x016F +#define MTXORB_FTDI_RANGE_0170_PID 0x0170 +#define MTXORB_FTDI_RANGE_0171_PID 0x0171 +#define MTXORB_FTDI_RANGE_0172_PID 0x0172 +#define MTXORB_FTDI_RANGE_0173_PID 0x0173 +#define MTXORB_FTDI_RANGE_0174_PID 0x0174 +#define MTXORB_FTDI_RANGE_0175_PID 0x0175 +#define MTXORB_FTDI_RANGE_0176_PID 0x0176 +#define MTXORB_FTDI_RANGE_0177_PID 0x0177 +#define MTXORB_FTDI_RANGE_0178_PID 0x0178 +#define MTXORB_FTDI_RANGE_0179_PID 0x0179 +#define MTXORB_FTDI_RANGE_017A_PID 0x017A +#define MTXORB_FTDI_RANGE_017B_PID 0x017B +#define MTXORB_FTDI_RANGE_017C_PID 0x017C +#define MTXORB_FTDI_RANGE_017D_PID 0x017D +#define MTXORB_FTDI_RANGE_017E_PID 0x017E +#define MTXORB_FTDI_RANGE_017F_PID 0x017F +#define MTXORB_FTDI_RANGE_0180_PID 0x0180 +#define MTXORB_FTDI_RANGE_0181_PID 0x0181 +#define MTXORB_FTDI_RANGE_0182_PID 0x0182 +#define MTXORB_FTDI_RANGE_0183_PID 0x0183 +#define MTXORB_FTDI_RANGE_0184_PID 0x0184 +#define MTXORB_FTDI_RANGE_0185_PID 0x0185 +#define MTXORB_FTDI_RANGE_0186_PID 0x0186 +#define MTXORB_FTDI_RANGE_0187_PID 0x0187 +#define MTXORB_FTDI_RANGE_0188_PID 0x0188 +#define MTXORB_FTDI_RANGE_0189_PID 0x0189 +#define MTXORB_FTDI_RANGE_018A_PID 0x018A +#define MTXORB_FTDI_RANGE_018B_PID 0x018B +#define MTXORB_FTDI_RANGE_018C_PID 0x018C +#define MTXORB_FTDI_RANGE_018D_PID 0x018D +#define MTXORB_FTDI_RANGE_018E_PID 0x018E +#define MTXORB_FTDI_RANGE_018F_PID 0x018F +#define MTXORB_FTDI_RANGE_0190_PID 0x0190 +#define MTXORB_FTDI_RANGE_0191_PID 0x0191 +#define MTXORB_FTDI_RANGE_0192_PID 0x0192 +#define MTXORB_FTDI_RANGE_0193_PID 0x0193 +#define MTXORB_FTDI_RANGE_0194_PID 0x0194 +#define MTXORB_FTDI_RANGE_0195_PID 0x0195 +#define MTXORB_FTDI_RANGE_0196_PID 0x0196 +#define MTXORB_FTDI_RANGE_0197_PID 0x0197 +#define MTXORB_FTDI_RANGE_0198_PID 0x0198 +#define MTXORB_FTDI_RANGE_0199_PID 0x0199 +#define MTXORB_FTDI_RANGE_019A_PID 0x019A +#define MTXORB_FTDI_RANGE_019B_PID 0x019B +#define MTXORB_FTDI_RANGE_019C_PID 0x019C +#define MTXORB_FTDI_RANGE_019D_PID 0x019D +#define MTXORB_FTDI_RANGE_019E_PID 0x019E +#define MTXORB_FTDI_RANGE_019F_PID 0x019F +#define MTXORB_FTDI_RANGE_01A0_PID 0x01A0 +#define MTXORB_FTDI_RANGE_01A1_PID 0x01A1 +#define MTXORB_FTDI_RANGE_01A2_PID 0x01A2 +#define MTXORB_FTDI_RANGE_01A3_PID 0x01A3 +#define MTXORB_FTDI_RANGE_01A4_PID 0x01A4 +#define MTXORB_FTDI_RANGE_01A5_PID 0x01A5 +#define MTXORB_FTDI_RANGE_01A6_PID 0x01A6 +#define MTXORB_FTDI_RANGE_01A7_PID 0x01A7 +#define MTXORB_FTDI_RANGE_01A8_PID 0x01A8 +#define MTXORB_FTDI_RANGE_01A9_PID 0x01A9 +#define MTXORB_FTDI_RANGE_01AA_PID 0x01AA +#define MTXORB_FTDI_RANGE_01AB_PID 0x01AB +#define MTXORB_FTDI_RANGE_01AC_PID 0x01AC +#define MTXORB_FTDI_RANGE_01AD_PID 0x01AD +#define MTXORB_FTDI_RANGE_01AE_PID 0x01AE +#define MTXORB_FTDI_RANGE_01AF_PID 0x01AF +#define MTXORB_FTDI_RANGE_01B0_PID 0x01B0 +#define MTXORB_FTDI_RANGE_01B1_PID 0x01B1 +#define MTXORB_FTDI_RANGE_01B2_PID 0x01B2 +#define MTXORB_FTDI_RANGE_01B3_PID 0x01B3 +#define MTXORB_FTDI_RANGE_01B4_PID 0x01B4 +#define MTXORB_FTDI_RANGE_01B5_PID 0x01B5 +#define MTXORB_FTDI_RANGE_01B6_PID 0x01B6 +#define MTXORB_FTDI_RANGE_01B7_PID 0x01B7 +#define MTXORB_FTDI_RANGE_01B8_PID 0x01B8 +#define MTXORB_FTDI_RANGE_01B9_PID 0x01B9 +#define MTXORB_FTDI_RANGE_01BA_PID 0x01BA +#define MTXORB_FTDI_RANGE_01BB_PID 0x01BB +#define MTXORB_FTDI_RANGE_01BC_PID 0x01BC +#define MTXORB_FTDI_RANGE_01BD_PID 0x01BD +#define MTXORB_FTDI_RANGE_01BE_PID 0x01BE +#define MTXORB_FTDI_RANGE_01BF_PID 0x01BF +#define MTXORB_FTDI_RANGE_01C0_PID 0x01C0 +#define MTXORB_FTDI_RANGE_01C1_PID 0x01C1 +#define MTXORB_FTDI_RANGE_01C2_PID 0x01C2 +#define MTXORB_FTDI_RANGE_01C3_PID 0x01C3 +#define MTXORB_FTDI_RANGE_01C4_PID 0x01C4 +#define MTXORB_FTDI_RANGE_01C5_PID 0x01C5 +#define MTXORB_FTDI_RANGE_01C6_PID 0x01C6 +#define MTXORB_FTDI_RANGE_01C7_PID 0x01C7 +#define MTXORB_FTDI_RANGE_01C8_PID 0x01C8 +#define MTXORB_FTDI_RANGE_01C9_PID 0x01C9 +#define MTXORB_FTDI_RANGE_01CA_PID 0x01CA +#define MTXORB_FTDI_RANGE_01CB_PID 0x01CB +#define MTXORB_FTDI_RANGE_01CC_PID 0x01CC +#define MTXORB_FTDI_RANGE_01CD_PID 0x01CD +#define MTXORB_FTDI_RANGE_01CE_PID 0x01CE +#define MTXORB_FTDI_RANGE_01CF_PID 0x01CF +#define MTXORB_FTDI_RANGE_01D0_PID 0x01D0 +#define MTXORB_FTDI_RANGE_01D1_PID 0x01D1 +#define MTXORB_FTDI_RANGE_01D2_PID 0x01D2 +#define MTXORB_FTDI_RANGE_01D3_PID 0x01D3 +#define MTXORB_FTDI_RANGE_01D4_PID 0x01D4 +#define MTXORB_FTDI_RANGE_01D5_PID 0x01D5 +#define MTXORB_FTDI_RANGE_01D6_PID 0x01D6 +#define MTXORB_FTDI_RANGE_01D7_PID 0x01D7 +#define MTXORB_FTDI_RANGE_01D8_PID 0x01D8 +#define MTXORB_FTDI_RANGE_01D9_PID 0x01D9 +#define MTXORB_FTDI_RANGE_01DA_PID 0x01DA +#define MTXORB_FTDI_RANGE_01DB_PID 0x01DB +#define MTXORB_FTDI_RANGE_01DC_PID 0x01DC +#define MTXORB_FTDI_RANGE_01DD_PID 0x01DD +#define MTXORB_FTDI_RANGE_01DE_PID 0x01DE +#define MTXORB_FTDI_RANGE_01DF_PID 0x01DF +#define MTXORB_FTDI_RANGE_01E0_PID 0x01E0 +#define MTXORB_FTDI_RANGE_01E1_PID 0x01E1 +#define MTXORB_FTDI_RANGE_01E2_PID 0x01E2 +#define MTXORB_FTDI_RANGE_01E3_PID 0x01E3 +#define MTXORB_FTDI_RANGE_01E4_PID 0x01E4 +#define MTXORB_FTDI_RANGE_01E5_PID 0x01E5 +#define MTXORB_FTDI_RANGE_01E6_PID 0x01E6 +#define MTXORB_FTDI_RANGE_01E7_PID 0x01E7 +#define MTXORB_FTDI_RANGE_01E8_PID 0x01E8 +#define MTXORB_FTDI_RANGE_01E9_PID 0x01E9 +#define MTXORB_FTDI_RANGE_01EA_PID 0x01EA +#define MTXORB_FTDI_RANGE_01EB_PID 0x01EB +#define MTXORB_FTDI_RANGE_01EC_PID 0x01EC +#define MTXORB_FTDI_RANGE_01ED_PID 0x01ED +#define MTXORB_FTDI_RANGE_01EE_PID 0x01EE +#define MTXORB_FTDI_RANGE_01EF_PID 0x01EF +#define MTXORB_FTDI_RANGE_01F0_PID 0x01F0 +#define MTXORB_FTDI_RANGE_01F1_PID 0x01F1 +#define MTXORB_FTDI_RANGE_01F2_PID 0x01F2 +#define MTXORB_FTDI_RANGE_01F3_PID 0x01F3 +#define MTXORB_FTDI_RANGE_01F4_PID 0x01F4 +#define MTXORB_FTDI_RANGE_01F5_PID 0x01F5 +#define MTXORB_FTDI_RANGE_01F6_PID 0x01F6 +#define MTXORB_FTDI_RANGE_01F7_PID 0x01F7 +#define MTXORB_FTDI_RANGE_01F8_PID 0x01F8 +#define MTXORB_FTDI_RANGE_01F9_PID 0x01F9 +#define MTXORB_FTDI_RANGE_01FA_PID 0x01FA +#define MTXORB_FTDI_RANGE_01FB_PID 0x01FB +#define MTXORB_FTDI_RANGE_01FC_PID 0x01FC +#define MTXORB_FTDI_RANGE_01FD_PID 0x01FD +#define MTXORB_FTDI_RANGE_01FE_PID 0x01FE +#define MTXORB_FTDI_RANGE_01FF_PID 0x01FF + + /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ -- cgit v1.2.3 From 62d104d0deeabd4148e49eba729d963e740e205f Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 20 May 2008 20:06:28 +0100 Subject: USB: Firmware loader driver for USB Apple iSight camera Uninitialised Apple iSight drivers present with a distinctive USB ID. Once firmware has been uploaded, they disconnect and reconnect with a new ID. At this point they can be driven by the uvcvideo driver. As this is unique to the Apple cameras and not functionality shared by any other UVC devices, it makes sense to provide the firmware loading functionality in a separate driver. This driver will read an isight.fw file extracted from the Apple driver using the tools at http://bersace03.free.fr/ift/ and upload it to the camera. It will also handle the case where the device loses its firmware during hibernation and must have it reloaded. Signed-off-by: Matthew Garrett Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/Kconfig | 11 ++++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/isight_firmware.c | 131 +++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 drivers/usb/misc/isight_firmware.c (limited to 'drivers/usb') diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index a53db1d4e07a..eb6c06979f3b 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -269,3 +269,14 @@ config USB_TEST See for more information, including sample test device firmware and "how to use it". +config USB_ISIGHTFW + tristate "iSight firmware loading support" + depends on USB + help + This driver loads firmware for USB Apple iSight cameras, allowing + them to be driven by the USB video class driver available at + http://linux-uvc.berlios.de + + The firmware for this driver must be extracted from the MacOS + driver beforehand. Tools for doing so are available at + http://bersace03.free.fr diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index b68e6b774f1a..aba091cb5ec0 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_USB_EMI62) += emi62.o obj-$(CONFIG_USB_FTDI_ELAN) += ftdi-elan.o obj-$(CONFIG_USB_IDMOUSE) += idmouse.o obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o +obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o obj-$(CONFIG_USB_LCD) += usblcd.o obj-$(CONFIG_USB_LD) += ldusb.o obj-$(CONFIG_USB_LED) += usbled.o diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c new file mode 100644 index 000000000000..390e04885536 --- /dev/null +++ b/drivers/usb/misc/isight_firmware.c @@ -0,0 +1,131 @@ +/* + * Driver for loading USB isight firmware + * + * Copyright (C) 2008 Matthew Garrett + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * The USB isight cameras in recent Apples are roughly compatible with the USB + * video class specification, and can be driven by uvcvideo. However, they + * need firmware to be loaded beforehand. After firmware loading, the device + * detaches from the USB bus and reattaches with a new device ID. It can then + * be claimed by the uvc driver. + * + * The firmware is non-free and must be extracted by the user. Tools to do this + * are available at http://bersace03.free.fr/ift/ + * + * The isight firmware loading was reverse engineered by Johannes Berg + * , and this driver is based on code by Ronald + * Bultje + */ + +#include +#include +#include +#include + +static struct usb_device_id id_table[] = { + {USB_DEVICE(0x05ac, 0x8300)}, + {}, +}; + +MODULE_DEVICE_TABLE(usb, id_table); + +static int isight_firmware_load(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + int llen, len, req, ret = 0; + const struct firmware *firmware; + unsigned char *buf; + unsigned char data[4]; + char *ptr; + + if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { + printk(KERN_ERR "Unable to load isight firmware\n"); + return -ENODEV; + } + + ptr = firmware->data; + + if (usb_control_msg + (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, + 300) != 1) { + printk(KERN_ERR + "Failed to initialise isight firmware loader\n"); + ret = -ENODEV; + goto out; + } + + while (1) { + memcpy(data, ptr, 4); + len = (data[0] << 8 | data[1]); + req = (data[2] << 8 | data[3]); + ptr += 4; + + if (len == 0x8001) + break; /* success */ + else if (len == 0) + continue; + + for (; len > 0; req += 50) { + llen = len > 50 ? 50 : len; + len -= llen; + + buf = kmalloc(llen, GFP_KERNEL); + memcpy(buf, ptr, llen); + + ptr += llen; + + if (usb_control_msg + (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0, + buf, llen, 300) != llen) { + printk(KERN_ERR + "Failed to load isight firmware\n"); + kfree(buf); + ret = -ENODEV; + goto out; + } + + kfree(buf); + } + } + if (usb_control_msg + (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, + 300) != 1) { + printk(KERN_ERR "isight firmware loading completion failed\n"); + ret = -ENODEV; + } +out: + release_firmware(firmware); + return ret; +} + +static void isight_firmware_disconnect(struct usb_interface *intf) +{ +} + +static struct usb_driver isight_firmware_driver = { + .name = "isight_firmware", + .probe = isight_firmware_load, + .disconnect = isight_firmware_disconnect, + .id_table = id_table, +}; + +static int __init isight_firmware_init(void) +{ + return usb_register(&isight_firmware_driver); +} + +static void __exit isight_firmware_exit(void) +{ + usb_deregister(&isight_firmware_driver); +} + +module_init(isight_firmware_init); +module_exit(isight_firmware_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Matthew Garrett "); -- cgit v1.2.3 From e16362a0c8d90e9adbfe477acbe32b021823fb22 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:37:34 -0400 Subject: USB: fix possible deadlock involving sysfs attributes There is a potential deadlock when the usb_generic driver is unbound from a device. The problem is that generic_disconnect() is called with the device lock held, and it removes a bunch of device attributes from sysfs. If a user task happens to be running an attribute method at the time, the removal will block until the method returns. But at least one of the attribute methods (the store routine for power/level) needs to acquire the device lock! This patch (as1093) eliminates the deadlock by moving the calls to create and remove the sysfs attributes from the usb_generic driver into usb_new_device() and usb_disconnect(), where they can be invoked without holding the device lock. Besides, the other sysfs attributes are created when the device is registered and removed when the device is unregistered. So it seems only fitting for the extra attributes to be created and removed at the same time. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/generic.c | 5 ----- drivers/usb/core/hub.c | 9 +++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index c1cb94e9f242..7e912f21fd36 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -155,9 +155,6 @@ static int generic_probe(struct usb_device *udev) { int err, c; - /* put device-specific files into sysfs */ - usb_create_sysfs_dev_files(udev); - /* Choose and set the configuration. This registers the interfaces * with the driver core and lets interface drivers bind to them. */ @@ -189,8 +186,6 @@ static void generic_disconnect(struct usb_device *udev) * unconfigure the device */ if (udev->actconfig) usb_set_configuration(udev, -1); - - usb_remove_sysfs_dev_files(udev); } #ifdef CONFIG_PM diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index eb57fcc701d7..1a3d2879bc1d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1326,6 +1326,12 @@ void usb_disconnect(struct usb_device **pdev) usb_unlock_device(udev); + /* Remove the device-specific files from sysfs. This must be + * done with udev unlocked, because some of the attribute + * routines try to acquire the device lock. + */ + usb_remove_sysfs_dev_files(udev); + /* Unregister the device. The device driver is responsible * for removing the device files from usbfs and sysfs and for * de-configuring the device. @@ -1541,6 +1547,9 @@ int usb_new_device(struct usb_device *udev) goto fail; } + /* put device-specific files into sysfs */ + usb_create_sysfs_dev_files(udev); + /* Tell the world! */ announce_device(udev); return err; -- cgit v1.2.3 From 217a9081d8e69026186067711131b77f0ce219ed Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:40:42 -0400 Subject: USB: add all configs to the "descriptors" attribute This patch (as1094) changes the output of the "descriptors" binary attribute. Now it will contain the device descriptor followed by all the configuration descriptors, not just the descriptor for the current config. Userspace libraries want to have access to the kernel's cached descriptor information, so they can learn about device characteristics without having to wake up suspended devices. So far the only user of this attribute is the new libusb-1.0 library; thus changing its contents shouldn't cause any problems. This should be considered for 2.6.26, if for no other reason than to minimize the range of releases in which the attribute contains only the current config descriptor. Also, it doesn't hurt that the patch removes the device locking -- which was formerly needed in order to know for certain which config was indeed current. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index c783cb111847..5e1f5d55bf04 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -588,35 +588,33 @@ read_descriptors(struct kobject *kobj, struct bin_attribute *attr, container_of(kobj, struct device, kobj)); size_t nleft = count; size_t srclen, n; + int cfgno; + void *src; - usb_lock_device(udev); - - /* The binary attribute begins with the device descriptor */ - srclen = sizeof(struct usb_device_descriptor); - if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + (char *) &udev->descriptor, n); - nleft -= n; - buf += n; - off = 0; - } else { - off -= srclen; - } - - /* Then follows the raw descriptor entry for the current - * configuration (config plus subsidiary descriptors). + /* The binary attribute begins with the device descriptor. + * Following that are the raw descriptor entries for all the + * configurations (config plus subsidiary descriptors). */ - if (udev->actconfig) { - int cfgno = udev->actconfig - udev->config; - - srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); + for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations && + nleft > 0; ++cfgno) { + if (cfgno < 0) { + src = &udev->descriptor; + srclen = sizeof(struct usb_device_descriptor); + } else { + src = udev->rawdescriptors[cfgno]; + srclen = __le16_to_cpu(udev->config[cfgno].desc. + wTotalLength); + } if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + udev->rawdescriptors[cfgno], n); + n = min(nleft, srclen - (size_t) off); + memcpy(buf, src + off, n); nleft -= n; + buf += n; + off = 0; + } else { + off -= srclen; } } - usb_unlock_device(udev); return count - nleft; } -- cgit v1.2.3 From a8e5177583e975fc1f7c621c93956f494df9b979 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:58:11 -0400 Subject: USB: EHCI: fix up root-hub TT mess This patch (as1095) cleans up the HCD glue and several of the EHCI bus-glue files. The ehci->is_tdi_rh_tt flag is redundant, since it means the same thing as the hcd->has_tt flag, so it is removed and the other flag used in its place. Some of the bus-glue files didn't get the relinquish_port method added to their hc_driver structures. Although that routine currently doesn't do anything for controllers with an integrated TT, in the future it might. So the patch adds it where it is missing. Lastly, some of the bus-glue files have erroneous entries for their hc_driver's suspend and resume methods. These method pointers are specific to PCI and shouldn't be used otherwise. (The patch also includes an invisible whitespace fix.) Signed-off-by: Alan Stern Acked-by: David Brownell --- drivers/usb/host/ehci-fsl.c | 6 +----- drivers/usb/host/ehci-ixp4xx.c | 3 ++- drivers/usb/host/ehci-orion.c | 7 ++----- drivers/usb/host/ehci-pci.c | 3 +-- drivers/usb/host/ehci-ppc-of.c | 1 + drivers/usb/host/ehci.h | 3 +-- 6 files changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 6d9bed6c1f48..4843062e6e21 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -269,7 +269,7 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) if (retval) return retval; - ehci->is_tdi_rh_tt = 1; + hcd->has_tt = 1; ehci->sbrn = 0x20; @@ -295,10 +295,6 @@ static const struct hc_driver ehci_fsl_hc_driver = { */ .reset = ehci_fsl_setup, .start = ehci_run, -#ifdef CONFIG_PM - .suspend = ehci_bus_suspend, - .resume = ehci_bus_resume, -#endif .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 601c8795a854..539257f15924 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c @@ -26,7 +26,7 @@ static int ixp4xx_ehci_init(struct usb_hcd *hcd) + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - ehci->is_tdi_rh_tt = 1; + hcd->has_tt = 1; ehci_reset(ehci); retval = ehci_init(hcd); @@ -58,6 +58,7 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, #endif + .relinquish_port = ehci_relinquish_port, }; static int ixp4xx_ehci_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 3adfda813a7b..9c5266d02d6c 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -139,10 +139,6 @@ static const struct hc_driver ehci_orion_hc_driver = { */ .reset = ehci_orion_setup, .start = ehci_run, -#ifdef CONFIG_PM - .suspend = ehci_bus_suspend, - .resume = ehci_bus_resume, -#endif .stop = ehci_stop, .shutdown = ehci_shutdown, @@ -165,6 +161,7 @@ static const struct hc_driver ehci_orion_hc_driver = { .hub_control = ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, + .relinquish_port = ehci_relinquish_port, }; static void __init @@ -250,7 +247,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev) ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - ehci->is_tdi_rh_tt = 1; + hcd->has_tt = 1; ehci->sbrn = 0x20; /* diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 5bb7f6bb13f3..6ff453f935e7 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -129,7 +129,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) switch (pdev->vendor) { case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { - ehci->is_tdi_rh_tt = 1; hcd->has_tt = 1; tdi_reset(ehci); } @@ -379,7 +378,7 @@ static const struct hc_driver ehci_pci_hc_driver = { .hub_control = ehci_hub_control, .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, + .relinquish_port = ehci_relinquish_port, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ee305b1f99ff..d94a2ef4944c 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -76,6 +76,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, #endif + .relinquish_port = ehci_relinquish_port, }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index bf92d209a1a9..3cb482308343 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -112,7 +112,6 @@ struct ehci_hcd { /* one per controller */ u32 command; /* SILICON QUIRKS */ - unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ unsigned no_selective_suspend:1; unsigned has_fsl_port_bug:1; /* FreeScale */ unsigned big_endian_mmio:1; @@ -678,7 +677,7 @@ struct ehci_fstn { * needed (mostly in root hub code). */ -#define ehci_is_TDI(e) ((e)->is_tdi_rh_tt) +#define ehci_is_TDI(e) (ehci_to_hcd(e)->has_tt) /* Returns the speed of a device attached to a port on the root hub. */ static inline unsigned int -- cgit v1.2.3 From 3a31155cfff0935e4b178f3dca733d2d60d2eb8d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:58:29 -0400 Subject: USB: EHCI: suppress unwanted error messages This patch (as1096) fixes an annoying problem: When a full-speed or low-speed device is plugged into an EHCI controller, it fails to enumerate at high speed and then is handed over to the companion controller. But usbcore logs a misleading and unwanted error message when the high-speed enumeration fails. The patch adds a new HCD method, port_handed_over, which asks whether a port has been handed over to a companion controller. If it has, the error message is suppressed. Signed-off-by: Alan Stern CC: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.h | 2 ++ drivers/usb/core/hub.c | 6 +++++- drivers/usb/host/ehci-au1xxx.c | 1 + drivers/usb/host/ehci-fsl.c | 1 + drivers/usb/host/ehci-hub.c | 10 ++++++++++ drivers/usb/host/ehci-ixp4xx.c | 1 + drivers/usb/host/ehci-orion.c | 1 + drivers/usb/host/ehci-pci.c | 1 + drivers/usb/host/ehci-ppc-of.c | 1 + drivers/usb/host/ehci-ppc-soc.c | 1 + drivers/usb/host/ehci-ps3.c | 1 + 11 files changed, 25 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1e4b81e9eb50..a0bf5df6cb6f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -213,6 +213,8 @@ struct hc_driver { /* force handover of high-speed port to full-speed companion */ void (*relinquish_port)(struct usb_hcd *, int); + /* has a port been handed over to a companion? */ + int (*port_handed_over)(struct usb_hcd *, int); }; extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1a3d2879bc1d..8eb4da332f56 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2753,7 +2753,11 @@ loop: if ((status == -ENOTCONN) || (status == -ENOTSUPP)) break; } - dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1); + if (hub->hdev->parent || + !hcd->driver->port_handed_over || + !(hcd->driver->port_handed_over)(hcd, port1)) + dev_err(hub_dev, "unable to enumerate USB device on port %d\n", + port1); done: hub_port_disable(hub, port1, 1); diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 8b5f991e949c..08a4335401a9 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -223,6 +223,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 4843062e6e21..7370d6187c64 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -318,6 +318,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; static int ehci_fsl_drv_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 382587c4457c..d613dc9e9c05 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -875,3 +875,13 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) set_owner(ehci, --portnum, PORT_OWNER); } +static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 __iomem *reg; + + if (ehci_is_TDI(ehci)) + return 0; + reg = &ehci->regs->port_status[portnum - 1]; + return ehci_readl(ehci, reg) & PORT_OWNER; +} diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index 539257f15924..9d042f220097 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c @@ -59,6 +59,7 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { .bus_resume = ehci_bus_resume, #endif .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; static int ixp4xx_ehci_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 9c5266d02d6c..ab625f0ba1d9 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -162,6 +162,7 @@ static const struct hc_driver ehci_orion_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; static void __init diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 6ff453f935e7..c46a58f9181d 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -379,6 +379,7 @@ static const struct hc_driver ehci_pci_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index d94a2ef4944c..b018deed2e8f 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -77,6 +77,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { .bus_resume = ehci_bus_resume, #endif .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index 6c76036783a1..529590eb4037 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c @@ -163,6 +163,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { .bus_suspend = ehci_bus_suspend, .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 69782221bcf3..37e6abeb794c 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -73,6 +73,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { .bus_resume = ehci_bus_resume, #endif .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, }; static int ps3_ehci_probe(struct ps3_system_bus_device *dev) -- cgit v1.2.3 From d1f114d12bb4db3147e1b1342ae31083c5a79c84 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:58:58 -0400 Subject: USB: EHCI: fix remote-wakeup regression This patch (as1097) fixes a bug in the remote-wakeup handling in ehci-hcd. The driver currently does not keep track of whether the change-suspend feature is enabled for each port; the feature is automatically reset the first time it is read. But recent changes to the hub driver require that the feature be read at least twice in order to work properly. A bit-vector is added for storing the change-suspend feature values. Signed-off-by: Alan Stern Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 6 ++++-- drivers/usb/host/ehci.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index d613dc9e9c05..740835bb8575 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -609,7 +609,7 @@ static int ehci_hub_control ( } break; case USB_PORT_FEAT_C_SUSPEND: - /* we auto-clear this feature */ + clear_bit(wIndex, &ehci->port_c_suspend); break; case USB_PORT_FEAT_POWER: if (HCS_PPC (ehci->hcs_params)) @@ -688,7 +688,7 @@ static int ehci_hub_control ( /* resume completed? */ else if (time_after_eq(jiffies, ehci->reset_done[wIndex])) { - status |= 1 << USB_PORT_FEAT_C_SUSPEND; + set_bit(wIndex, &ehci->port_c_suspend); ehci->reset_done[wIndex] = 0; /* stop resume signaling */ @@ -765,6 +765,8 @@ static int ehci_hub_control ( status |= 1 << USB_PORT_FEAT_RESET; if (temp & PORT_POWER) status |= 1 << USB_PORT_FEAT_POWER; + if (test_bit(wIndex, &ehci->port_c_suspend)) + status |= 1 << USB_PORT_FEAT_C_SUSPEND; #ifndef VERBOSE_DEBUG if (status & ~0xffff) /* only if wPortChange is interesting */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 3cb482308343..35a03095757e 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */ dedicated to the companion controller */ unsigned long owned_ports; /* which ports are owned by the companion during a bus suspend */ + unsigned long port_c_suspend; /* which ports have + the change-suspend feature turned on */ /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ -- cgit v1.2.3 From b40e43fcc532fa44a375a37d592e32cd0d50fe7a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:59:10 -0400 Subject: USB: EHCI: fix bug in Iso scheduling This patch (as1098) changes the way ehci-hcd schedules its periodic Iso transfers. That the current scheduling code is wrong is clear on the face of it: Sometimes it returns -EL2NSYNC (meaning that an URB couldn't be scheduled because it was submitted too late), but it does this even when the URB_ISO_ASAP flag is set (meaning the URB should be scheduled as soon as possible). The new code properly implements as-soon-as-possible scheduling, assigning the next unexpired slot as the URB's starting point. It also is more careful about checking for Iso URB completion: It doesn't bother to check for activity during frames that are already over, and it allows for the possibility that some of the URB's packets may have raced the hardware when they were submitted and so never got used (the packet status is set to -EXDEV). This fixes problems several people have experienced with USB video applications. Signed-off-by: Alan Stern Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 67 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index be575e46eac3..b7853c8bac0f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1349,18 +1349,27 @@ iso_stream_schedule ( /* when's the last uframe this urb could start? */ max = now + mod; - /* typical case: reuse current schedule. stream is still active, - * and no gaps from host falling behind (irq delays etc) + /* Typical case: reuse current schedule, stream is still active. + * Hopefully there are no gaps from the host falling behind + * (irq delays etc), but if there are we'll take the next + * slot in the schedule, implicitly assuming URB_ISO_ASAP. */ if (likely (!list_empty (&stream->td_list))) { start = stream->next_uframe; if (start < now) start += mod; - if (likely ((start + sched->span) < max)) - goto ready; - /* else fell behind; someday, try to reschedule */ - status = -EL2NSYNC; - goto fail; + + /* Fell behind (by up to twice the slop amount)? */ + if (start >= max - 2 * 8 * SCHEDULE_SLOP) + start += stream->interval * DIV_ROUND_UP( + max - start, stream->interval) - mod; + + /* Tried to schedule too far into the future? */ + if (unlikely((start + sched->span) >= max)) { + status = -EFBIG; + goto fail; + } + goto ready; } /* need to schedule; when's the next (u)frame we could start? @@ -1613,6 +1622,9 @@ itd_complete ( } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { desc->status = 0; desc->actual_length = EHCI_ITD_LENGTH (t); + } else { + /* URB was too late */ + desc->status = -EXDEV; } } @@ -2095,7 +2107,7 @@ done: static void scan_periodic (struct ehci_hcd *ehci) { - unsigned frame, clock, now_uframe, mod; + unsigned now_uframe, frame, clock, clock_frame, mod; unsigned modified; mod = ehci->periodic_size << 3; @@ -2111,6 +2123,7 @@ scan_periodic (struct ehci_hcd *ehci) else clock = now_uframe + mod - 1; clock %= mod; + clock_frame = clock >> 3; for (;;) { union ehci_shadow q, *q_p; @@ -2157,22 +2170,26 @@ restart: case Q_TYPE_ITD: /* If this ITD is still active, leave it for * later processing ... check the next entry. + * No need to check for activity unless the + * frame is current. */ - rmb (); - for (uf = 0; uf < 8 && live; uf++) { - if (0 == (q.itd->hw_transaction [uf] - & ITD_ACTIVE(ehci))) - continue; - incomplete = true; - q_p = &q.itd->itd_next; - hw_p = &q.itd->hw_next; - type = Q_NEXT_TYPE(ehci, + if (frame == clock_frame && live) { + rmb(); + for (uf = 0; uf < 8; uf++) { + if (q.itd->hw_transaction[uf] & + ITD_ACTIVE(ehci)) + break; + } + if (uf < 8) { + incomplete = true; + q_p = &q.itd->itd_next; + hw_p = &q.itd->hw_next; + type = Q_NEXT_TYPE(ehci, q.itd->hw_next); - q = *q_p; - break; + q = *q_p; + break; + } } - if (uf < 8 && live) - break; /* Take finished ITDs out of the schedule * and process them: recycle, maybe report @@ -2189,9 +2206,12 @@ restart: case Q_TYPE_SITD: /* If this SITD is still active, leave it for * later processing ... check the next entry. + * No need to check for activity unless the + * frame is current. */ - if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) - && live) { + if (frame == clock_frame && live && + (q.sitd->hw_results & + SITD_ACTIVE(ehci))) { incomplete = true; q_p = &q.sitd->sitd_next; hw_p = &q.sitd->hw_next; @@ -2260,6 +2280,7 @@ restart: /* rescan the rest of this frame, then ... */ clock = now; + clock_frame = clock >> 3; } else { now_uframe++; now_uframe %= mod; -- cgit v1.2.3 From fa38dfcc56b5f6cce787f9aaa5d1830509213802 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 20 May 2008 16:59:33 -0400 Subject: USB: EHCI: fix performance regression This patch (as1099) fixes a performance regression in ehci-hcd. The fundamental problem is that queue headers get removed from the schedule too quickly, since the code checks for a counter advancing rather than making an actual time-based check. The latency involved in removing the queue header and then relinking it can severely degrade certain kinds of workloads. The patch replaces a simple counter with a timestamp derived from the controller's uframe value. In addition, the delay for unlinking an idle queue header is increased from 5 ms to 10 ms; since some controllers (nVidia) have a latency of up to 1 ms for unlinking, this reduces the relative impact from 20% to 10%. Finally, a logical error left over from the IAA watchdog-timer conversion is corrected. Now the driver will always either unlink an idle queue header or set up a timer to unlink it later. The old code would sometimes fail to do either. Signed-off-by: Alan Stern Cc: David Brownell Cc: Leonid Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 3 ++- drivers/usb/host/ehci-q.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 369a8a5ea7bb..3e3c5d3ea0ad 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -84,7 +84,8 @@ static const char hcd_name [] = "ehci_hcd"; #define EHCI_IAA_MSECS 10 /* arbitrary */ #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ -#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ +#define EHCI_SHRINK_JIFFIES (HZ/100) /* async qh unlink delay */ +#define EHCI_SHRINK_UFRAMES (10*8) /* same value in uframes */ /* Initial IRQ latency: faster than hw default */ static int log2_irq_thresh = 0; // 0 to 6 diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index b85b54160cda..5200481deb27 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1116,8 +1116,7 @@ static void scan_async (struct ehci_hcd *ehci) struct ehci_qh *qh; enum ehci_timer_action action = TIMER_IO_WATCHDOG; - if (!++(ehci->stamp)) - ehci->stamp++; + ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); timer_action_done (ehci, TIMER_ASYNC_SHRINK); rescan: qh = ehci->async->qh_next.qh; @@ -1148,12 +1147,14 @@ rescan: * doesn't stay idle for long. * (plus, avoids some kind of re-activation race.) */ - if (list_empty (&qh->qtd_list)) { - if (qh->stamp == ehci->stamp) + if (list_empty(&qh->qtd_list) && + qh->qh_state == QH_STATE_LINKED) { + if (!ehci->reclaim && + ((ehci->stamp - qh->stamp) & 8191) >= + EHCI_SHRINK_UFRAMES) + start_unlink_async(ehci, qh); + else action = TIMER_ASYNC_SHRINK; - else if (!ehci->reclaim - && qh->qh_state == QH_STATE_LINKED) - start_unlink_async (ehci, qh); } qh = qh->qh_next.qh; -- cgit v1.2.3 From c7257bd2ecb7b4cc42f9f152c7c059258d434169 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 21 May 2008 13:53:01 -0400 Subject: USB: usb-storage: unusual_devs update for Cypress ATACB This patch (as1101) updates the unusual_devs entry for the Cypress ATACB pass-through. The protocol field is changed from US_PR_BULK to US_PR_DEVICE, since the Cypress devices already set bInterfaceProtocol to Bulk-only. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1b09578cbb10..5d56893fc1cc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -405,7 +405,7 @@ UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100, UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, "Cypress", "Cypress AT2LP", - US_SC_CYP_ATACB, US_PR_BULK, NULL, + US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0), #endif -- cgit v1.2.3 From c5f23b0e08d84f4efc20dece04d7b6796dcc6774 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Mon, 26 May 2008 21:33:58 +0200 Subject: USB: Fix M600i unusual_devs entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that the unusual_devs entry for the Motorola M600i needs another flag. This patch adds it. Thanks to Atte André Jensen . Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 5d56893fc1cc..599bb1299f62 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1522,7 +1522,7 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, "Sony Ericsson", "M600i", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), /* Reported by Kevin Cernekee * Tested on hardware version 1.10. -- cgit v1.2.3 From 2a8bc9e7cfb1761a62ea897b407ea13ec887fd0c Mon Sep 17 00:00:00 2001 From: Javier Smaldone Date: Mon, 26 May 2008 21:44:00 +0200 Subject: USB: Add support for ROKR W5 in unusual_devs.h This patch adds support for rev 2 of an existing unusual_devs entry enabling ROKR W5s to work. Greg, please apply. From: Javier Smaldone Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 599bb1299f62..45fe3663fa7f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1716,10 +1716,12 @@ UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001, /* * Patch by Pete Zaitcev * Report by Mark Patton. Red Hat bz#208928. + * Added support for rev 0x0002 (Motorola ROKR W5) + * by Javier Smaldone */ -UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0001, +UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0002, "Motorola", - "RAZR V3i", + "RAZR V3i/ROKR W5", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), -- cgit v1.2.3 From 598eff6d2f3b8805232edc5f4a6b0c1e698dc482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Rebe?= Date: Tue, 27 May 2008 09:05:46 +0200 Subject: USB: add another scanner quirk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like the HP53{00,70} scanner other devices of the OEM Avision require the USB_QUIRK_STRING_FETCH_255 to correct set a configuration with "recent" Linux kernels. Signed-off-by: René Rebe Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 2e2019390290..3da1ab4b389d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -47,6 +47,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* Edirol SD-20 */ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Avision AV600U */ + { USB_DEVICE(0x0638, 0x0a13), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, + /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, -- cgit v1.2.3 From 4be2fa186d54758296d30c565d7b5111dd45b000 Mon Sep 17 00:00:00 2001 From: Steve Murphy Date: Fri, 23 May 2008 23:39:05 +0530 Subject: USB: pl2303: another product ID I've just got a USB GPRS/EDGE modem branded Manufacturer Micromax Model MMX610U (see http://www.airtel.in/level2_t3data.aspx?path=1/106/179) working by adding another product ID to pl2303. Modem info reports same module as Max Arnold's i.e.SIMCOM SIM600 but with product ID 0x0612 (cf Ox0611). From: Steve Murphy Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 234c5eea95a2..103195abd417 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 3bdefe020501..cff160abb130 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -14,6 +14,7 @@ #define PL2303_PRODUCT_ID_PHAROS 0xaaa0 #define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 #define PL2303_PRODUCT_ID_ALDIGA 0x0611 +#define PL2303_PRODUCT_ID_MMX 0x0612 #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 -- cgit v1.2.3 From a7f3872c43b8001f01000f79583d422c6995f98d Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Wed, 28 May 2008 23:58:18 +0200 Subject: USB: usb-serial: option: Don't match Huawei driver CD images Add the interface info matching to all Huawei cards, as they all also contain a Mass Storage Device interface (usually containing Windows drivers) which should not get bound by this driver. See also drivers/usb/storage/unusual_devs.h Signed-off-by: Michael Karcher Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6cecd2c12b1d..43cfde83a93b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -236,25 +236,25 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418) }, - { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ -- cgit v1.2.3 From 185e3dead35dacb79c8cca1073fd67a26d09a0d7 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Thu, 29 May 2008 21:04:45 +0800 Subject: USB: fsl_usb2_udc: fix recursive lock UDC needs to release lock before calling out to gadget driver, since it may need to reenter. The change fixes kernel BUG observed on rt kernel. > kernel BUG at kernel/rtmutex.c:683! > stopped custom tracer. > Oops: Exception in kernel mode, sig: 5 [#1] > PREEMPT MPC834x ITX > NIP: c021629c LR: c0216270 CTR: 00000000 > REGS: df761d70 TRAP: 0700 Not tainted (2.6.23.9-rt13) > MSR: 00021032 CR: 28000022 XER: 00000000 > TASK = df632080[241] 'IRQ-38' THREAD: df760000 > GPR00: 00000001 df761e20 df632080 00000000 11111111 00000000 df761e6c > 00000000 > GPR08: df761e48 00000000 df761e50 00000000 80000000 ede5cdde 1fffd000 > 00800000 > GPR16: ffffffff 00000000 007fff00 00000040 00000000 007ffeb0 00000000 > 1fff8b08 > GPR24: 00000000 00000026 00000000 df79a320 c026b2e8 c02240bc 00009032 > df79a320 > NIP [c021629c] rt_spin_lock_slowlock+0x9c/0x200 > LR [c0216270] rt_spin_lock_slowlock+0x70/0x200 > Call Trace: > [df761e20] [c0216270] rt_spin_lock_slowlock+0x70/0x200 (unreliable) > [df761e90] [c0182828] fsl_ep_disable+0xcc/0x154 > [df761eb0] [c0184d30] eth_reset_config+0x88/0x1d0 > [df761ed0] [c0184ec0] eth_disconnect+0x48/0x64 > [df761ef0] [c01831a4] reset_queues+0x60/0x78 > [df761f00] [c0183b74] fsl_udc_irq+0x9b8/0xa58 > [df761f50] [c003ef30] handle_IRQ_event+0x64/0x100 > [df761f80] [c003f758] thread_simple_irq+0x6c/0xc8 > [df761fa0] [c003f888] do_irqd+0xd4/0x2e4 > [df761fd0] [c0032284] kthread+0x50/0x8c > [df761ff0] [c000f9b4] kernel_thread+0x44/0x60 Signed-off-by: Li Yang Cc: Eugene T. Bordenkircher Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 651b82701394..18687543d7fa 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1627,7 +1627,9 @@ static int reset_queues(struct fsl_udc *udc) udc_reset_ep_queue(udc, pipe); /* report disconnect; the driver is already quiesced */ + spin_unlock(&udc->lock); udc->driver->disconnect(&udc->gadget); + spin_lock(&udc->lock); return 0; } -- cgit v1.2.3 From bb7e6984ecaebe6989d0e781e303469255871432 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 May 2008 19:43:27 -0700 Subject: Revert "USB: EHCI: fix performance regression" This reverts commit fa38dfcc56b5f6cce787f9aaa5d1830509213802. It wasn't really a regression and David and Alan are still working through the issues reported. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 3 +-- drivers/usb/host/ehci-q.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 3e3c5d3ea0ad..369a8a5ea7bb 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -84,8 +84,7 @@ static const char hcd_name [] = "ehci_hcd"; #define EHCI_IAA_MSECS 10 /* arbitrary */ #define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ -#define EHCI_SHRINK_JIFFIES (HZ/100) /* async qh unlink delay */ -#define EHCI_SHRINK_UFRAMES (10*8) /* same value in uframes */ +#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ /* Initial IRQ latency: faster than hw default */ static int log2_irq_thresh = 0; // 0 to 6 diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 5200481deb27..b85b54160cda 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1116,7 +1116,8 @@ static void scan_async (struct ehci_hcd *ehci) struct ehci_qh *qh; enum ehci_timer_action action = TIMER_IO_WATCHDOG; - ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); + if (!++(ehci->stamp)) + ehci->stamp++; timer_action_done (ehci, TIMER_ASYNC_SHRINK); rescan: qh = ehci->async->qh_next.qh; @@ -1147,14 +1148,12 @@ rescan: * doesn't stay idle for long. * (plus, avoids some kind of re-activation race.) */ - if (list_empty(&qh->qtd_list) && - qh->qh_state == QH_STATE_LINKED) { - if (!ehci->reclaim && - ((ehci->stamp - qh->stamp) & 8191) >= - EHCI_SHRINK_UFRAMES) - start_unlink_async(ehci, qh); - else + if (list_empty (&qh->qtd_list)) { + if (qh->stamp == ehci->stamp) action = TIMER_ASYNC_SHRINK; + else if (!ehci->reclaim + && qh->qh_state == QH_STATE_LINKED) + start_unlink_async (ehci, qh); } qh = qh->qh_next.qh; -- cgit v1.2.3 From 76e6f2526ff69eba466f583d94beb7cf6b0bddd6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 2 Jun 2008 10:59:02 +0100 Subject: usb/c67x00 endianness annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/c67x00/c67x00-ll-hpi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c index 5100fbbf6cb0..a9636f43bca2 100644 --- a/drivers/usb/c67x00/c67x00-ll-hpi.c +++ b/drivers/usb/c67x00/c67x00-ll-hpi.c @@ -120,7 +120,7 @@ static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) * Only data is little endian, addr has cpu endianess */ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) + __le16 *data, u16 count) { unsigned long flags; int i; @@ -129,7 +129,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, hpi_write_reg(dev, HPI_ADDR, addr); for (i = 0; i < count; i++) - hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++)); + hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++)); spin_unlock_irqrestore(&dev->hpi.lock, flags); } @@ -138,7 +138,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, * Only data is little endian, addr has cpu endianess */ static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, - u16 *data, u16 count) + __le16 *data, u16 count) { unsigned long flags; int i; @@ -146,7 +146,7 @@ static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, spin_lock_irqsave(&dev->hpi.lock, flags); hpi_write_reg(dev, HPI_ADDR, addr); for (i = 0; i < count; i++) - *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA)); + *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA)); spin_unlock_irqrestore(&dev->hpi.lock, flags); } @@ -425,7 +425,7 @@ void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, len--; } - hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2); + hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2); buf += len & ~0x01; addr += len & ~0x01; len &= 0x01; @@ -456,7 +456,7 @@ void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, len--; } - hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2); + hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2); buf += len & ~0x01; addr += len & ~0x01; len &= 0x01; -- cgit v1.2.3 From fa4144b758d58341d4e082ac2af259e97fbcbeee Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 2 Jun 2008 10:59:02 +0100 Subject: cdc-wdm endianness fixes * wMaxPacketSize is le16; copying it to a field of local structure and then using that field as host-endian (size of object to be allocated) is broken. * bMaxPacketSize0 is 8-bit; feeding it to le16_to_cpu() is bogus and since the result is used as host-endian, it's not even misspelled cpu_to_le16(). Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/class/cdc-wdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 107666d4e2ec..731db051070a 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -611,8 +611,8 @@ next_desc: goto err; } - desc->wMaxPacketSize = ep->wMaxPacketSize; - desc->bMaxPacketSize0 = cpu_to_le16(udev->descriptor.bMaxPacketSize0); + desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); + desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) -- cgit v1.2.3 From 6399e7acbf9193c7d48827329ca592a1c8dc9e69 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 2 Jun 2008 10:59:02 +0100 Subject: isp1760-if iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/host/isp1760-if.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 440bf94f0d4c..c9db3fe98726 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -104,8 +104,8 @@ static u32 nxp_pci_io_base; static u32 iolength; static u32 pci_mem_phy0; static u32 length; -static u8 *chip_addr; -static u8 *iobase; +static u8 __iomem *chip_addr; +static u8 __iomem *iobase; static int __devinit isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) -- cgit v1.2.3 From 77d11ba993bf1258f242b6a4ee0230aec8c6c8a4 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 9 Jun 2008 16:00:32 +0900 Subject: usb: r8a66597-hcd: Add support for SH7723 USB host R8A66597 is similar to SH7723 USB 2.0 Host/Function module. In addition, the USB of SH7366 is compatible with SH7723. It can support SH7723 USB host by changing Kconfig. Signed-off-by: Yoshihiro Shimoda Acked-by: Greg Kroah-Hartman Signed-off-by: Paul Mundt --- drivers/usb/host/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1ef6df395e0c..228797e54f9c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -300,8 +300,8 @@ config USB_R8A66597_HCD module will be called r8a66597-hcd. config SUPERH_ON_CHIP_R8A66597 - boolean "Enable SuperH on-chip USB like the R8A66597" - depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 + boolean "Enable SuperH on-chip R8A66597 USB" + depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723) help - Renesas SuperH processor has USB like the R8A66597. - This driver supported processor is SH7366. + This driver enables support for the on-chip R8A66597 in the + SH7366 and SH7723 processors. -- cgit v1.2.3 From 6460a261b5893e769a314c246faec31bbc4aad9c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 2 Jun 2008 21:21:03 +0200 Subject: USB: fix build bug in USB_ISIGHTFW USB: fix build bug in USB_ISIGHTFW -tip tree testing found this build bug: drivers/built-in.o: In function `isight_firmware_load': isight_firmware.c:(.text+0x1ade08): undefined reference to `request_firmware' isight_firmware.c:(.text+0x1adf9c): undefined reference to `release_firmware' select FW_LOADER in USB_ISIGHTFW. From: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index eb6c06979f3b..001789c9a11a 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -272,6 +272,7 @@ config USB_TEST config USB_ISIGHTFW tristate "iSight firmware loading support" depends on USB + select FW_LOADER help This driver loads firmware for USB Apple iSight cameras, allowing them to be driven by the USB video class driver available at -- cgit v1.2.3 From 62b5884875fcd4babf6c0c377046f226abbfe491 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 6 Jun 2008 12:35:15 -0700 Subject: isight_firmware: Avoid crash on loading invalid firmware Different tools generate slightly different formats of the isight firmware. Ensure that the firmware buffer is not overrun, while still ensuring that the correct amount of data is written if trailing data is present. Signed-off-by: Matthew Garrett Report-by: Justin Mattock Tested-by: Justin Mattock Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/isight_firmware.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 390e04885536..9f30aa1f8a5d 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -39,9 +39,12 @@ static int isight_firmware_load(struct usb_interface *intf, struct usb_device *dev = interface_to_usbdev(intf); int llen, len, req, ret = 0; const struct firmware *firmware; - unsigned char *buf; + unsigned char *buf = kmalloc(50, GFP_KERNEL); unsigned char data[4]; - char *ptr; + u8 *ptr; + + if (!buf) + return -ENOMEM; if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { printk(KERN_ERR "Unable to load isight firmware\n"); @@ -59,7 +62,7 @@ static int isight_firmware_load(struct usb_interface *intf, goto out; } - while (1) { + while (ptr+4 <= firmware->data+firmware->size) { memcpy(data, ptr, 4); len = (data[0] << 8 | data[1]); req = (data[2] << 8 | data[3]); @@ -71,10 +74,14 @@ static int isight_firmware_load(struct usb_interface *intf, continue; for (; len > 0; req += 50) { - llen = len > 50 ? 50 : len; + llen = min(len, 50); len -= llen; - - buf = kmalloc(llen, GFP_KERNEL); + if (ptr+llen > firmware->data+firmware->size) { + printk(KERN_ERR + "Malformed isight firmware"); + ret = -ENODEV; + goto out; + } memcpy(buf, ptr, llen); ptr += llen; @@ -89,16 +96,18 @@ static int isight_firmware_load(struct usb_interface *intf, goto out; } - kfree(buf); } } + if (usb_control_msg (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, 300) != 1) { printk(KERN_ERR "isight firmware loading completion failed\n"); ret = -ENODEV; } + out: + kfree(buf); release_firmware(firmware); return ret; } -- cgit v1.2.3 From e6942d633be61f1638e08c56ab8244fc9f1c61e3 Mon Sep 17 00:00:00 2001 From: Nate Case Date: Wed, 21 May 2008 16:28:20 -0500 Subject: USB: isp1760: Assign resource fields before adding hcd This fixes the bogus "io mem 0x00000000" message printed during driver init due to hcd->rsrc_start being assigned after the call to usb_add_hcd(). Signed-off-by: Nate Case Acked-by: Sebastian Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index c9cec8738261..65aa5ecf569a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2207,14 +2207,14 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, goto err_put; } - ret = usb_add_hcd(hcd, irq, irqflags); - if (ret) - goto err_unmap; - hcd->irq = irq; hcd->rsrc_start = res_start; hcd->rsrc_len = res_len; + ret = usb_add_hcd(hcd, irq, irqflags); + if (ret) + goto err_unmap; + return hcd; err_unmap: -- cgit v1.2.3 From 5340ba827b6269ccd2dcfd3d966626d9dd75d5d4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 10 Jun 2008 14:59:43 -0400 Subject: USB: don't use reset-resume if drivers don't support it This patch tries to identify which devices are able to accept reset-resume handling, by checking that there is at least one interface driver bound and that all of the drivers have a reset_resume method defined. If these conditions don't hold then during resume processing, the device is logicall disconnected. This is only a temporary fix. Later on we will explicitly unbind drivers that can't handle reset-resumes. Signed-off-by: Linus Torvalds Signed-off-by: Alan Stern Cc: Oliver Neukum Cc: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8eb4da332f56..94789be54ca3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub) #ifdef CONFIG_PM +/* Try to identify which devices need USB-PERSIST handling */ +static int persistent_device(struct usb_device *udev) +{ + int i; + int retval; + struct usb_host_config *actconfig; + + /* Explicitly not marked persistent? */ + if (!udev->persist_enabled) + return 0; + + /* No active config? */ + actconfig = udev->actconfig; + if (!actconfig) + return 0; + + /* FIXME! We should check whether it's open here or not! */ + + /* + * Check that all the interface drivers have a + * 'reset_resume' entrypoint + */ + retval = 0; + for (i = 0; i < actconfig->desc.bNumInterfaces; i++) { + struct usb_interface *intf; + struct usb_driver *driver; + + intf = actconfig->interface[i]; + if (!intf->dev.driver) + continue; + driver = to_usb_driver(intf->dev.driver); + if (!driver->reset_resume) + return 0; + /* + * We have at least one driver, and that one + * has a reset_resume method. + */ + retval = 1; + } + return retval; +} + static void hub_restart(struct usb_hub *hub, int type) { struct usb_device *hdev = hub->hdev; @@ -689,8 +731,8 @@ static void hub_restart(struct usb_hub *hub, int type) * turn off the various status changes to prevent * khubd from disconnecting it later. */ - if (udev->persist_enabled && status == 0 && - !(portstatus & USB_PORT_STAT_ENABLE)) { + if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) && + persistent_device(udev)) { if (portchange & USB_PORT_STAT_C_ENABLE) clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_ENABLE); -- cgit v1.2.3