diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-29 00:08:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-29 00:08:14 -0400 |
commit | 1f419cadff55f548e7356ffebdb9e1b5a8c22275 (patch) | |
tree | 07c04d053322e9913a6b445b2fe00510299e97cf /drivers | |
parent | 974f7bc5781d3fc16e32d8908c6e48592e767dd2 (diff) | |
parent | 4303fc6f055cf1a7ec63c3c3fd777b91b7d576f1 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
Diffstat (limited to 'drivers')
132 files changed, 4027 insertions, 4497 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 1a109a6dd953..65670be6ff1a 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | # Rewritten to use lists instead of if-statements. | 5 | # Rewritten to use lists instead of if-statements. |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-$(CONFIG_PCI) += pci/ | 8 | obj-$(CONFIG_PCI) += pci/ usb/ |
9 | obj-$(CONFIG_PARISC) += parisc/ | 9 | obj-$(CONFIG_PARISC) += parisc/ |
10 | obj-y += video/ | 10 | obj-y += video/ |
11 | obj-$(CONFIG_ACPI) += acpi/ | 11 | obj-$(CONFIG_ACPI) += acpi/ |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 15e6a8f951f1..0d2e101e4f15 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -30,23 +30,6 @@ LIST_HEAD(dpm_off_irq); | |||
30 | DECLARE_MUTEX(dpm_sem); | 30 | DECLARE_MUTEX(dpm_sem); |
31 | DECLARE_MUTEX(dpm_list_sem); | 31 | DECLARE_MUTEX(dpm_list_sem); |
32 | 32 | ||
33 | /* | ||
34 | * PM Reference Counting. | ||
35 | */ | ||
36 | |||
37 | static inline void device_pm_hold(struct device * dev) | ||
38 | { | ||
39 | if (dev) | ||
40 | atomic_inc(&dev->power.pm_users); | ||
41 | } | ||
42 | |||
43 | static inline void device_pm_release(struct device * dev) | ||
44 | { | ||
45 | if (dev) | ||
46 | atomic_dec(&dev->power.pm_users); | ||
47 | } | ||
48 | |||
49 | |||
50 | /** | 33 | /** |
51 | * device_pm_set_parent - Specify power dependency. | 34 | * device_pm_set_parent - Specify power dependency. |
52 | * @dev: Device who needs power. | 35 | * @dev: Device who needs power. |
@@ -62,10 +45,8 @@ static inline void device_pm_release(struct device * dev) | |||
62 | 45 | ||
63 | void device_pm_set_parent(struct device * dev, struct device * parent) | 46 | void device_pm_set_parent(struct device * dev, struct device * parent) |
64 | { | 47 | { |
65 | struct device * old_parent = dev->power.pm_parent; | 48 | put_device(dev->power.pm_parent); |
66 | device_pm_release(old_parent); | 49 | dev->power.pm_parent = get_device(parent); |
67 | dev->power.pm_parent = parent; | ||
68 | device_pm_hold(parent); | ||
69 | } | 50 | } |
70 | EXPORT_SYMBOL_GPL(device_pm_set_parent); | 51 | EXPORT_SYMBOL_GPL(device_pm_set_parent); |
71 | 52 | ||
@@ -75,7 +56,6 @@ int device_pm_add(struct device * dev) | |||
75 | 56 | ||
76 | pr_debug("PM: Adding info for %s:%s\n", | 57 | pr_debug("PM: Adding info for %s:%s\n", |
77 | dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); | 58 | dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); |
78 | atomic_set(&dev->power.pm_users, 0); | ||
79 | down(&dpm_list_sem); | 59 | down(&dpm_list_sem); |
80 | list_add_tail(&dev->power.entry, &dpm_active); | 60 | list_add_tail(&dev->power.entry, &dpm_active); |
81 | device_pm_set_parent(dev, dev->parent); | 61 | device_pm_set_parent(dev, dev->parent); |
@@ -91,7 +71,7 @@ void device_pm_remove(struct device * dev) | |||
91 | dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); | 71 | dev->bus ? dev->bus->name : "No Bus", dev->kobj.name); |
92 | down(&dpm_list_sem); | 72 | down(&dpm_list_sem); |
93 | dpm_sysfs_remove(dev); | 73 | dpm_sysfs_remove(dev); |
94 | device_pm_release(dev->power.pm_parent); | 74 | put_device(dev->power.pm_parent); |
95 | list_del_init(&dev->power.entry); | 75 | list_del_init(&dev->power.entry); |
96 | up(&dpm_list_sem); | 76 | up(&dpm_list_sem); |
97 | } | 77 | } |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 2e700d795cf1..fb3d35a9e101 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -67,9 +67,6 @@ extern int suspend_device(struct device *, pm_message_t); | |||
67 | * runtime.c | 67 | * runtime.c |
68 | */ | 68 | */ |
69 | 69 | ||
70 | extern int dpm_runtime_suspend(struct device *, pm_message_t); | ||
71 | extern void dpm_runtime_resume(struct device *); | ||
72 | |||
73 | #else /* CONFIG_PM */ | 70 | #else /* CONFIG_PM */ |
74 | 71 | ||
75 | 72 | ||
@@ -82,14 +79,4 @@ static inline void device_pm_remove(struct device * dev) | |||
82 | 79 | ||
83 | } | 80 | } |
84 | 81 | ||
85 | static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) | ||
86 | { | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static inline void dpm_runtime_resume(struct device * dev) | ||
91 | { | ||
92 | |||
93 | } | ||
94 | |||
95 | #endif | 82 | #endif |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index e8f0519f5dfa..adbc3148c039 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -36,6 +36,7 @@ void dpm_runtime_resume(struct device * dev) | |||
36 | runtime_resume(dev); | 36 | runtime_resume(dev); |
37 | up(&dpm_sem); | 37 | up(&dpm_sem); |
38 | } | 38 | } |
39 | EXPORT_SYMBOL(dpm_runtime_resume); | ||
39 | 40 | ||
40 | 41 | ||
41 | /** | 42 | /** |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index ed4d5006fe62..bfb23d543ff7 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -1512,7 +1512,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1512 | scmd->nsg = 1; | 1512 | scmd->nsg = 1; |
1513 | sg = &scmd->sgv[0]; | 1513 | sg = &scmd->sgv[0]; |
1514 | sg->page = virt_to_page(sc->top_sense); | 1514 | sg->page = virt_to_page(sc->top_sense); |
1515 | sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1); | 1515 | sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1); |
1516 | sg->length = UB_SENSE_SIZE; | 1516 | sg->length = UB_SENSE_SIZE; |
1517 | scmd->len = UB_SENSE_SIZE; | 1517 | scmd->len = UB_SENSE_SIZE; |
1518 | scmd->lun = cmd->lun; | 1518 | scmd->lun = cmd->lun; |
@@ -1891,7 +1891,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, | |||
1891 | cmd->nsg = 1; | 1891 | cmd->nsg = 1; |
1892 | sg = &cmd->sgv[0]; | 1892 | sg = &cmd->sgv[0]; |
1893 | sg->page = virt_to_page(p); | 1893 | sg->page = virt_to_page(p); |
1894 | sg->offset = (unsigned int)p & (PAGE_SIZE-1); | 1894 | sg->offset = (unsigned long)p & (PAGE_SIZE-1); |
1895 | sg->length = 8; | 1895 | sg->length = 8; |
1896 | cmd->len = 8; | 1896 | cmd->len = 8; |
1897 | cmd->lun = lun; | 1897 | cmd->lun = lun; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ee1605906a3e..bbd9c2323d8c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -7,6 +7,9 @@ | |||
7 | * | 7 | * |
8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | 8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> |
9 | * | 9 | * |
10 | * Init/reset quirks for USB host controllers should be in the | ||
11 | * USB quirks file, where their drivers can access reuse it. | ||
12 | * | ||
10 | * The bridge optimization stuff has been removed. If you really | 13 | * The bridge optimization stuff has been removed. If you really |
11 | * have a silly BIOS which is unable to set your host bridge right, | 14 | * have a silly BIOS which is unable to set your host bridge right, |
12 | * use the PowerTweak utility (see http://powertweak.sourceforge.net). | 15 | * use the PowerTweak utility (see http://powertweak.sourceforge.net). |
@@ -645,28 +648,6 @@ static void quirk_via_irq(struct pci_dev *dev) | |||
645 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); | 648 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
646 | 649 | ||
647 | /* | 650 | /* |
648 | * PIIX3 USB: We have to disable USB interrupts that are | ||
649 | * hardwired to PIRQD# and may be shared with an | ||
650 | * external device. | ||
651 | * | ||
652 | * Legacy Support Register (LEGSUP): | ||
653 | * bit13: USB PIRQ Enable (USBPIRQDEN), | ||
654 | * bit4: Trap/SMI On IRQ Enable (USBSMIEN). | ||
655 | * | ||
656 | * We mask out all r/wc bits, too. | ||
657 | */ | ||
658 | static void __devinit quirk_piix3_usb(struct pci_dev *dev) | ||
659 | { | ||
660 | u16 legsup; | ||
661 | |||
662 | pci_read_config_word(dev, 0xc0, &legsup); | ||
663 | legsup &= 0x50ef; | ||
664 | pci_write_config_word(dev, 0xc0, legsup); | ||
665 | } | ||
666 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3_usb ); | ||
667 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_2, quirk_piix3_usb ); | ||
668 | |||
669 | /* | ||
670 | * VIA VT82C598 has its device ID settable and many BIOSes | 651 | * VIA VT82C598 has its device ID settable and many BIOSes |
671 | * set it to the ID of VT82C597 for backward compatibility. | 652 | * set it to the ID of VT82C597 for backward compatibility. |
672 | * We need to switch it off to be able to recognize the real | 653 | * We need to switch it off to be able to recognize the real |
@@ -1039,234 +1020,6 @@ static void __init quirk_sis_96x_smbus(struct pci_dev *dev) | |||
1039 | pci_read_config_byte(dev, 0x77, &val); | 1020 | pci_read_config_byte(dev, 0x77, &val); |
1040 | } | 1021 | } |
1041 | 1022 | ||
1042 | |||
1043 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | ||
1044 | #define UHCI_USBCMD 0 /* command register */ | ||
1045 | #define UHCI_USBSTS 2 /* status register */ | ||
1046 | #define UHCI_USBINTR 4 /* interrupt register */ | ||
1047 | #define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ | ||
1048 | #define UHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
1049 | #define UHCI_USBCMD_GRESET (1 << 2) /* Global reset */ | ||
1050 | #define UHCI_USBCMD_CONFIGURE (1 << 6) /* config semaphore */ | ||
1051 | #define UHCI_USBSTS_HALTED (1 << 5) /* HCHalted bit */ | ||
1052 | |||
1053 | #define OHCI_CONTROL 0x04 | ||
1054 | #define OHCI_CMDSTATUS 0x08 | ||
1055 | #define OHCI_INTRSTATUS 0x0c | ||
1056 | #define OHCI_INTRENABLE 0x10 | ||
1057 | #define OHCI_INTRDISABLE 0x14 | ||
1058 | #define OHCI_OCR (1 << 3) /* ownership change request */ | ||
1059 | #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ | ||
1060 | #define OHCI_INTR_OC (1 << 30) /* ownership change */ | ||
1061 | |||
1062 | #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ | ||
1063 | #define EHCI_USBCMD 0 /* command register */ | ||
1064 | #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
1065 | #define EHCI_USBSTS 4 /* status register */ | ||
1066 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | ||
1067 | #define EHCI_USBINTR 8 /* interrupt register */ | ||
1068 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | ||
1069 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | ||
1070 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | ||
1071 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | ||
1072 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | ||
1073 | |||
1074 | int usb_early_handoff __devinitdata = 0; | ||
1075 | static int __init usb_handoff_early(char *str) | ||
1076 | { | ||
1077 | usb_early_handoff = 1; | ||
1078 | return 0; | ||
1079 | } | ||
1080 | __setup("usb-handoff", usb_handoff_early); | ||
1081 | |||
1082 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | ||
1083 | { | ||
1084 | unsigned long base = 0; | ||
1085 | int wait_time, delta; | ||
1086 | u16 val, sts; | ||
1087 | int i; | ||
1088 | |||
1089 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
1090 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | ||
1091 | base = pci_resource_start(pdev, i); | ||
1092 | break; | ||
1093 | } | ||
1094 | |||
1095 | if (!base) | ||
1096 | return; | ||
1097 | |||
1098 | /* | ||
1099 | * stop controller | ||
1100 | */ | ||
1101 | sts = inw(base + UHCI_USBSTS); | ||
1102 | val = inw(base + UHCI_USBCMD); | ||
1103 | val &= ~(u16)(UHCI_USBCMD_RUN | UHCI_USBCMD_CONFIGURE); | ||
1104 | outw(val, base + UHCI_USBCMD); | ||
1105 | |||
1106 | /* | ||
1107 | * wait while it stops if it was running | ||
1108 | */ | ||
1109 | if ((sts & UHCI_USBSTS_HALTED) == 0) | ||
1110 | { | ||
1111 | wait_time = 1000; | ||
1112 | delta = 100; | ||
1113 | |||
1114 | do { | ||
1115 | outw(0x1f, base + UHCI_USBSTS); | ||
1116 | udelay(delta); | ||
1117 | wait_time -= delta; | ||
1118 | val = inw(base + UHCI_USBSTS); | ||
1119 | if (val & UHCI_USBSTS_HALTED) | ||
1120 | break; | ||
1121 | } while (wait_time > 0); | ||
1122 | } | ||
1123 | |||
1124 | /* | ||
1125 | * disable interrupts & legacy support | ||
1126 | */ | ||
1127 | outw(0, base + UHCI_USBINTR); | ||
1128 | outw(0x1f, base + UHCI_USBSTS); | ||
1129 | pci_read_config_word(pdev, UHCI_USBLEGSUP, &val); | ||
1130 | if (val & 0xbf) | ||
1131 | pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); | ||
1132 | |||
1133 | } | ||
1134 | |||
1135 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||
1136 | { | ||
1137 | void __iomem *base; | ||
1138 | int wait_time; | ||
1139 | |||
1140 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
1141 | pci_resource_len(pdev, 0)); | ||
1142 | if (base == NULL) return; | ||
1143 | |||
1144 | if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
1145 | wait_time = 500; /* 0.5 seconds */ | ||
1146 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | ||
1147 | writel(OHCI_OCR, base + OHCI_CMDSTATUS); | ||
1148 | while (wait_time > 0 && | ||
1149 | readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
1150 | wait_time -= 10; | ||
1151 | msleep(10); | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | /* | ||
1156 | * disable interrupts | ||
1157 | */ | ||
1158 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
1159 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
1160 | |||
1161 | iounmap(base); | ||
1162 | } | ||
1163 | |||
1164 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | ||
1165 | { | ||
1166 | int wait_time, delta; | ||
1167 | void __iomem *base, *op_reg_base; | ||
1168 | u32 hcc_params, val, temp; | ||
1169 | u8 cap_length; | ||
1170 | |||
1171 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
1172 | pci_resource_len(pdev, 0)); | ||
1173 | if (base == NULL) return; | ||
1174 | |||
1175 | cap_length = readb(base); | ||
1176 | op_reg_base = base + cap_length; | ||
1177 | hcc_params = readl(base + EHCI_HCC_PARAMS); | ||
1178 | hcc_params = (hcc_params >> 8) & 0xff; | ||
1179 | if (hcc_params) { | ||
1180 | pci_read_config_dword(pdev, | ||
1181 | hcc_params + EHCI_USBLEGSUP, | ||
1182 | &val); | ||
1183 | if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { | ||
1184 | /* | ||
1185 | * Ok, BIOS is in smm mode, try to hand off... | ||
1186 | */ | ||
1187 | pci_read_config_dword(pdev, | ||
1188 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1189 | &temp); | ||
1190 | pci_write_config_dword(pdev, | ||
1191 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1192 | temp | EHCI_USBLEGCTLSTS_SOOE); | ||
1193 | val |= EHCI_USBLEGSUP_OS; | ||
1194 | pci_write_config_dword(pdev, | ||
1195 | hcc_params + EHCI_USBLEGSUP, | ||
1196 | val); | ||
1197 | |||
1198 | wait_time = 500; | ||
1199 | do { | ||
1200 | msleep(10); | ||
1201 | wait_time -= 10; | ||
1202 | pci_read_config_dword(pdev, | ||
1203 | hcc_params + EHCI_USBLEGSUP, | ||
1204 | &val); | ||
1205 | } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); | ||
1206 | if (!wait_time) { | ||
1207 | /* | ||
1208 | * well, possibly buggy BIOS... | ||
1209 | */ | ||
1210 | printk(KERN_WARNING "EHCI early BIOS handoff " | ||
1211 | "failed (BIOS bug ?)\n"); | ||
1212 | pci_write_config_dword(pdev, | ||
1213 | hcc_params + EHCI_USBLEGSUP, | ||
1214 | EHCI_USBLEGSUP_OS); | ||
1215 | pci_write_config_dword(pdev, | ||
1216 | hcc_params + EHCI_USBLEGCTLSTS, | ||
1217 | 0); | ||
1218 | } | ||
1219 | } | ||
1220 | } | ||
1221 | |||
1222 | /* | ||
1223 | * halt EHCI & disable its interrupts in any case | ||
1224 | */ | ||
1225 | val = readl(op_reg_base + EHCI_USBSTS); | ||
1226 | if ((val & EHCI_USBSTS_HALTED) == 0) { | ||
1227 | val = readl(op_reg_base + EHCI_USBCMD); | ||
1228 | val &= ~EHCI_USBCMD_RUN; | ||
1229 | writel(val, op_reg_base + EHCI_USBCMD); | ||
1230 | |||
1231 | wait_time = 2000; | ||
1232 | delta = 100; | ||
1233 | do { | ||
1234 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
1235 | udelay(delta); | ||
1236 | wait_time -= delta; | ||
1237 | val = readl(op_reg_base + EHCI_USBSTS); | ||
1238 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | ||
1239 | break; | ||
1240 | } | ||
1241 | } while (wait_time > 0); | ||
1242 | } | ||
1243 | writel(0, op_reg_base + EHCI_USBINTR); | ||
1244 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
1245 | |||
1246 | iounmap(base); | ||
1247 | |||
1248 | return; | ||
1249 | } | ||
1250 | |||
1251 | |||
1252 | |||
1253 | static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||
1254 | { | ||
1255 | if (!usb_early_handoff) | ||
1256 | return; | ||
1257 | |||
1258 | if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ | ||
1259 | quirk_usb_handoff_uhci(pdev); | ||
1260 | } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ | ||
1261 | quirk_usb_handoff_ohci(pdev); | ||
1262 | } else if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x20)) { /* EHCI */ | ||
1263 | quirk_usb_disable_ehci(pdev); | ||
1264 | } | ||
1265 | |||
1266 | return; | ||
1267 | } | ||
1268 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||
1269 | |||
1270 | /* | 1023 | /* |
1271 | * ... This is further complicated by the fact that some SiS96x south | 1024 | * ... This is further complicated by the fact that some SiS96x south |
1272 | * bridges pretend to be 85C503/5513 instead. In that case see if we | 1025 | * bridges pretend to be 85C503/5513 instead. In that case see if we |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index df014c2a7c54..a50c2bc506f2 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB) += core/ | |||
8 | 8 | ||
9 | obj-$(CONFIG_USB_MON) += mon/ | 9 | obj-$(CONFIG_USB_MON) += mon/ |
10 | 10 | ||
11 | obj-$(CONFIG_PCI) += host/ | ||
11 | obj-$(CONFIG_USB_EHCI_HCD) += host/ | 12 | obj-$(CONFIG_USB_EHCI_HCD) += host/ |
12 | obj-$(CONFIG_USB_ISP116X_HCD) += host/ | 13 | obj-$(CONFIG_USB_ISP116X_HCD) += host/ |
13 | obj-$(CONFIG_USB_OHCI_HCD) += host/ | 14 | obj-$(CONFIG_USB_OHCI_HCD) += host/ |
@@ -17,7 +18,6 @@ obj-$(CONFIG_ETRAX_USB_HOST) += host/ | |||
17 | 18 | ||
18 | obj-$(CONFIG_USB_ACM) += class/ | 19 | obj-$(CONFIG_USB_ACM) += class/ |
19 | obj-$(CONFIG_USB_AUDIO) += class/ | 20 | obj-$(CONFIG_USB_AUDIO) += class/ |
20 | obj-$(CONFIG_USB_BLUETOOTH_TTY) += class/ | ||
21 | obj-$(CONFIG_USB_MIDI) += class/ | 21 | obj-$(CONFIG_USB_MIDI) += class/ |
22 | obj-$(CONFIG_USB_PRINTER) += class/ | 22 | obj-$(CONFIG_USB_PRINTER) += class/ |
23 | 23 | ||
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 333e39bb105f..ef105a92a7bd 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig | |||
@@ -28,29 +28,6 @@ config USB_AUDIO | |||
28 | To compile this driver as a module, choose M here: the | 28 | To compile this driver as a module, choose M here: the |
29 | module will be called audio. | 29 | module will be called audio. |
30 | 30 | ||
31 | comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem" | ||
32 | depends on USB && BT | ||
33 | |||
34 | config USB_BLUETOOTH_TTY | ||
35 | tristate "USB Bluetooth TTY support" | ||
36 | depends on USB && BT=n | ||
37 | ---help--- | ||
38 | This driver implements a nonstandard tty interface to a Bluetooth | ||
39 | device that can be used only by specialized Bluetooth HCI software. | ||
40 | |||
41 | Say Y here if you want to use OpenBT Bluetooth stack (available | ||
42 | at <http://developer.axis.com/software>), or other TTY based | ||
43 | Bluetooth stacks, and want to connect a USB Bluetooth device | ||
44 | to your computer's USB port. | ||
45 | |||
46 | Do *not* enable this driver if you want to use generic Linux | ||
47 | Bluetooth support. | ||
48 | |||
49 | If in doubt, say N here. | ||
50 | |||
51 | To compile this driver as a module, choose M here: the | ||
52 | module will be called bluetty. | ||
53 | |||
54 | config USB_MIDI | 31 | config USB_MIDI |
55 | tristate "USB MIDI support" | 32 | tristate "USB MIDI support" |
56 | depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER | 33 | depends on USB && SOUND && OBSOLETE_OSS_USB_DRIVER |
diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile index 971e5497a3fd..229471247751 100644 --- a/drivers/usb/class/Makefile +++ b/drivers/usb/class/Makefile | |||
@@ -5,6 +5,5 @@ | |||
5 | 5 | ||
6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o | 6 | obj-$(CONFIG_USB_ACM) += cdc-acm.o |
7 | obj-$(CONFIG_USB_AUDIO) += audio.o | 7 | obj-$(CONFIG_USB_AUDIO) += audio.o |
8 | obj-$(CONFIG_USB_BLUETOOTH_TTY) += bluetty.o | ||
9 | obj-$(CONFIG_USB_MIDI) += usb-midi.o | 8 | obj-$(CONFIG_USB_MIDI) += usb-midi.o |
10 | obj-$(CONFIG_USB_PRINTER) += usblp.o | 9 | obj-$(CONFIG_USB_PRINTER) += usblp.o |
diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c deleted file mode 100644 index 524023327c49..000000000000 --- a/drivers/usb/class/bluetty.c +++ /dev/null | |||
@@ -1,1279 +0,0 @@ | |||
1 | /* | ||
2 | * bluetty.c Version 0.13 | ||
3 | * | ||
4 | * Copyright (C) 2000, 2001 Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * Copyright (C) 2000 Mark Douglas Corner <mcorner@umich.edu> | ||
6 | * | ||
7 | * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B | ||
8 | * | ||
9 | * (2001/11/30) Version 0.13 gkh | ||
10 | * - added locking patch from Masoodur Rahman <rmasoodu@in.ibm.com> | ||
11 | * - removed active variable, as open_count will do. | ||
12 | * | ||
13 | * (2001/07/09) Version 0.12 gkh | ||
14 | * - removed in_interrupt() call, as it doesn't make sense to do | ||
15 | * that anymore. | ||
16 | * | ||
17 | * (2001/06/05) Version 0.11 gkh | ||
18 | * - Fixed problem with read urb status saying that we have shutdown, | ||
19 | * and that we shouldn't resubmit the urb. Patch from unknown. | ||
20 | * | ||
21 | * (2001/05/28) Version 0.10 gkh | ||
22 | * - Fixed problem with using data from userspace in the bluetooth_write | ||
23 | * function as found by the CHECKER project. | ||
24 | * - Added a buffer to the write_urb_pool which reduces the number of | ||
25 | * buffers being created and destroyed for ever write. Also cleans | ||
26 | * up the logic a bit. | ||
27 | * - Added a buffer to the control_urb_pool which fixes a memory leak | ||
28 | * when the device is removed from the system. | ||
29 | * | ||
30 | * (2001/05/28) Version 0.9 gkh | ||
31 | * Fixed problem with bluetooth==NULL for bluetooth_read_bulk_callback | ||
32 | * which was found by both the CHECKER project and Mikko Rahkonen. | ||
33 | * | ||
34 | * (08/04/2001) gb | ||
35 | * Identify version on module load. | ||
36 | * | ||
37 | * (2001/03/10) Version 0.8 gkh | ||
38 | * Fixed problem with not unlinking interrupt urb on device close | ||
39 | * and resubmitting the read urb on error with bluetooth struct. | ||
40 | * Thanks to Narayan Mohanram <narayan@RovingNetworks.com> for the | ||
41 | * fixes. | ||
42 | * | ||
43 | * (11/29/2000) Version 0.7 gkh | ||
44 | * Fixed problem with overrunning the tty flip buffer. | ||
45 | * Removed unneeded NULL pointer initialization. | ||
46 | * | ||
47 | * (10/05/2000) Version 0.6 gkh | ||
48 | * Fixed bug with urb->dev not being set properly, now that the usb | ||
49 | * core needs it. | ||
50 | * Got a real major id number and name. | ||
51 | * | ||
52 | * (08/06/2000) Version 0.5 gkh | ||
53 | * Fixed problem of not resubmitting the bulk read urb if there is | ||
54 | * an error in the callback. Ericsson devices seem to need this. | ||
55 | * | ||
56 | * (07/11/2000) Version 0.4 gkh | ||
57 | * Fixed bug in disconnect for when we call tty_hangup | ||
58 | * Fixed bug in bluetooth_ctrl_msg where the bluetooth struct was not | ||
59 | * getting attached to the control urb properly. | ||
60 | * Fixed bug in bluetooth_write where we pay attention to the result | ||
61 | * of bluetooth_ctrl_msg. | ||
62 | * | ||
63 | * (08/03/2000) Version 0.3 gkh mdc | ||
64 | * Merged in Mark's changes to make the driver play nice with the Axis | ||
65 | * stack. | ||
66 | * Made the write bulk use an urb pool to enable larger transfers with | ||
67 | * fewer calls to the driver. | ||
68 | * Fixed off by one bug in acl pkt receive | ||
69 | * Made packet counters specific to each bluetooth device | ||
70 | * Added checks for zero length callbacks | ||
71 | * Added buffers for int and bulk packets. Had to do this otherwise | ||
72 | * packet types could intermingle. | ||
73 | * Made a control urb pool for the control messages. | ||
74 | * | ||
75 | * (07/11/2000) Version 0.2 gkh | ||
76 | * Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe | ||
77 | * function. | ||
78 | * | ||
79 | * (07/09/2000) Version 0.1 gkh | ||
80 | * Initial release. Has support for sending ACL data (which is really just | ||
81 | * a HCI frame.) Raw HCI commands and HCI events are not supported. | ||
82 | * A ioctl will probably be needed for the HCI commands and events in the | ||
83 | * future. All isoch endpoints are ignored at this time also. | ||
84 | * This driver should work for all currently shipping USB Bluetooth | ||
85 | * devices at this time :) | ||
86 | * | ||
87 | */ | ||
88 | |||
89 | /* | ||
90 | * This program is free software; you can redistribute it and/or modify | ||
91 | * it under the terms of the GNU General Public License as published by | ||
92 | * the Free Software Foundation; either version 2 of the License, or | ||
93 | * (at your option) any later version. | ||
94 | * | ||
95 | * This program is distributed in the hope that it will be useful, | ||
96 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
97 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
98 | * GNU General Public License for more details. | ||
99 | * | ||
100 | * You should have received a copy of the GNU General Public License | ||
101 | * along with this program; if not, write to the Free Software | ||
102 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
103 | */ | ||
104 | |||
105 | |||
106 | #include <linux/kernel.h> | ||
107 | #include <linux/errno.h> | ||
108 | #include <linux/init.h> | ||
109 | #include <linux/slab.h> | ||
110 | #include <linux/tty.h> | ||
111 | #include <linux/tty_driver.h> | ||
112 | #include <linux/tty_flip.h> | ||
113 | #include <linux/module.h> | ||
114 | #include <asm/uaccess.h> | ||
115 | |||
116 | #define DEBUG | ||
117 | #include <linux/usb.h> | ||
118 | |||
119 | /* | ||
120 | * Version Information | ||
121 | */ | ||
122 | #define DRIVER_VERSION "v0.13" | ||
123 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner" | ||
124 | #define DRIVER_DESC "USB Bluetooth tty driver" | ||
125 | |||
126 | /* define this if you have hardware that is not good */ | ||
127 | /*#define BTBUGGYHARDWARE */ | ||
128 | |||
129 | /* Class, SubClass, and Protocol codes that describe a Bluetooth device */ | ||
130 | #define WIRELESS_CLASS_CODE 0xe0 | ||
131 | #define RF_SUBCLASS_CODE 0x01 | ||
132 | #define BLUETOOTH_PROGRAMMING_PROTOCOL_CODE 0x01 | ||
133 | |||
134 | |||
135 | #define BLUETOOTH_TTY_MAJOR 216 /* real device node major id */ | ||
136 | #define BLUETOOTH_TTY_MINORS 256 /* whole lotta bluetooth devices */ | ||
137 | |||
138 | #define USB_BLUETOOTH_MAGIC 0x6d02 /* magic number for bluetooth struct */ | ||
139 | |||
140 | #define BLUETOOTH_CONTROL_REQUEST_TYPE 0x20 | ||
141 | |||
142 | /* Bluetooth packet types */ | ||
143 | #define CMD_PKT 0x01 | ||
144 | #define ACL_PKT 0x02 | ||
145 | #define SCO_PKT 0x03 | ||
146 | #define EVENT_PKT 0x04 | ||
147 | #define ERROR_PKT 0x05 | ||
148 | #define NEG_PKT 0x06 | ||
149 | |||
150 | /* Message sizes */ | ||
151 | #define MAX_EVENT_SIZE 0xFF | ||
152 | #define EVENT_HDR_SIZE 3 /* 2 for the header + 1 for the type indicator */ | ||
153 | #define EVENT_BUFFER_SIZE (MAX_EVENT_SIZE + EVENT_HDR_SIZE) | ||
154 | |||
155 | #define MAX_ACL_SIZE 0xFFFF | ||
156 | #define ACL_HDR_SIZE 5 /* 4 for the header + 1 for the type indicator */ | ||
157 | #define ACL_BUFFER_SIZE (MAX_ACL_SIZE + ACL_HDR_SIZE) | ||
158 | |||
159 | /* parity check flag */ | ||
160 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | ||
161 | |||
162 | #define CHAR2INT16(c1,c0) (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff)) | ||
163 | |||
164 | #define NUM_BULK_URBS 24 | ||
165 | #define NUM_CONTROL_URBS 16 | ||
166 | |||
167 | struct usb_bluetooth { | ||
168 | int magic; | ||
169 | struct usb_device * dev; | ||
170 | struct tty_driver * tty_driver; /* the tty_driver for this device */ | ||
171 | struct tty_struct * tty; /* the corresponding tty for this port */ | ||
172 | |||
173 | unsigned char minor; /* the starting minor number for this device */ | ||
174 | int throttle; /* throttled by tty layer */ | ||
175 | int open_count; | ||
176 | |||
177 | __u8 control_out_bInterfaceNum; | ||
178 | struct urb * control_urb_pool[NUM_CONTROL_URBS]; | ||
179 | struct usb_ctrlrequest dr[NUM_CONTROL_URBS]; | ||
180 | |||
181 | unsigned char * interrupt_in_buffer; | ||
182 | struct urb * interrupt_in_urb; | ||
183 | __u8 interrupt_in_endpointAddress; | ||
184 | __u8 interrupt_in_interval; | ||
185 | int interrupt_in_buffer_size; | ||
186 | |||
187 | unsigned char * bulk_in_buffer; | ||
188 | struct urb * read_urb; | ||
189 | __u8 bulk_in_endpointAddress; | ||
190 | int bulk_in_buffer_size; | ||
191 | |||
192 | int bulk_out_buffer_size; | ||
193 | __u8 bulk_out_endpointAddress; | ||
194 | |||
195 | wait_queue_head_t write_wait; | ||
196 | |||
197 | struct work_struct work; /* work queue entry for line discipline waking up */ | ||
198 | |||
199 | unsigned int int_packet_pos; | ||
200 | unsigned char int_buffer[EVENT_BUFFER_SIZE]; | ||
201 | unsigned int bulk_packet_pos; | ||
202 | unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */ | ||
203 | struct semaphore lock; | ||
204 | }; | ||
205 | |||
206 | |||
207 | /* local function prototypes */ | ||
208 | static int bluetooth_open (struct tty_struct *tty, struct file *filp); | ||
209 | static void bluetooth_close (struct tty_struct *tty, struct file *filp); | ||
210 | static int bluetooth_write (struct tty_struct *tty, const unsigned char *buf, int count); | ||
211 | static int bluetooth_write_room (struct tty_struct *tty); | ||
212 | static int bluetooth_chars_in_buffer (struct tty_struct *tty); | ||
213 | static void bluetooth_throttle (struct tty_struct *tty); | ||
214 | static void bluetooth_unthrottle (struct tty_struct *tty); | ||
215 | static int bluetooth_ioctl (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); | ||
216 | static void bluetooth_set_termios (struct tty_struct *tty, struct termios *old); | ||
217 | |||
218 | static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs); | ||
219 | static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs); | ||
220 | static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs); | ||
221 | static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs); | ||
222 | |||
223 | static int usb_bluetooth_probe (struct usb_interface *intf, | ||
224 | const struct usb_device_id *id); | ||
225 | static void usb_bluetooth_disconnect (struct usb_interface *intf); | ||
226 | |||
227 | |||
228 | static struct usb_device_id usb_bluetooth_ids [] = { | ||
229 | { USB_DEVICE_INFO(WIRELESS_CLASS_CODE, RF_SUBCLASS_CODE, BLUETOOTH_PROGRAMMING_PROTOCOL_CODE) }, | ||
230 | { } /* Terminating entry */ | ||
231 | }; | ||
232 | |||
233 | MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids); | ||
234 | |||
235 | static struct usb_driver usb_bluetooth_driver = { | ||
236 | .owner = THIS_MODULE, | ||
237 | .name = "bluetty", | ||
238 | .probe = usb_bluetooth_probe, | ||
239 | .disconnect = usb_bluetooth_disconnect, | ||
240 | .id_table = usb_bluetooth_ids, | ||
241 | }; | ||
242 | |||
243 | static struct tty_driver *bluetooth_tty_driver; | ||
244 | static struct usb_bluetooth *bluetooth_table[BLUETOOTH_TTY_MINORS]; | ||
245 | |||
246 | |||
247 | static inline int bluetooth_paranoia_check (struct usb_bluetooth *bluetooth, const char *function) | ||
248 | { | ||
249 | if (!bluetooth) { | ||
250 | dbg("%s - bluetooth == NULL", function); | ||
251 | return -1; | ||
252 | } | ||
253 | if (bluetooth->magic != USB_BLUETOOTH_MAGIC) { | ||
254 | dbg("%s - bad magic number for bluetooth", function); | ||
255 | return -1; | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | |||
262 | static inline struct usb_bluetooth* get_usb_bluetooth (struct usb_bluetooth *bluetooth, const char *function) | ||
263 | { | ||
264 | if (!bluetooth || | ||
265 | bluetooth_paranoia_check (bluetooth, function)) { | ||
266 | /* then say that we don't have a valid usb_bluetooth thing, which will | ||
267 | * end up generating -ENODEV return values */ | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | return bluetooth; | ||
272 | } | ||
273 | |||
274 | |||
275 | static inline struct usb_bluetooth *get_bluetooth_by_index (int index) | ||
276 | { | ||
277 | return bluetooth_table[index]; | ||
278 | } | ||
279 | |||
280 | |||
281 | static int bluetooth_ctrl_msg (struct usb_bluetooth *bluetooth, int request, int value, const unsigned char *buf, int len) | ||
282 | { | ||
283 | struct urb *urb = NULL; | ||
284 | struct usb_ctrlrequest *dr = NULL; | ||
285 | int i; | ||
286 | int status; | ||
287 | |||
288 | dbg ("%s", __FUNCTION__); | ||
289 | |||
290 | /* try to find a free urb in our list */ | ||
291 | for (i = 0; i < NUM_CONTROL_URBS; ++i) { | ||
292 | if (bluetooth->control_urb_pool[i]->status != -EINPROGRESS) { | ||
293 | urb = bluetooth->control_urb_pool[i]; | ||
294 | dr = &bluetooth->dr[i]; | ||
295 | break; | ||
296 | } | ||
297 | } | ||
298 | if (urb == NULL) { | ||
299 | dbg ("%s - no free urbs", __FUNCTION__); | ||
300 | return -ENOMEM; | ||
301 | } | ||
302 | |||
303 | /* keep increasing the urb transfer buffer to fit the size of the message */ | ||
304 | if (urb->transfer_buffer == NULL) { | ||
305 | urb->transfer_buffer = kmalloc (len, GFP_KERNEL); | ||
306 | if (urb->transfer_buffer == NULL) { | ||
307 | err ("%s - out of memory", __FUNCTION__); | ||
308 | return -ENOMEM; | ||
309 | } | ||
310 | } | ||
311 | if (urb->transfer_buffer_length < len) { | ||
312 | kfree(urb->transfer_buffer); | ||
313 | urb->transfer_buffer = kmalloc (len, GFP_KERNEL); | ||
314 | if (urb->transfer_buffer == NULL) { | ||
315 | err ("%s - out of memory", __FUNCTION__); | ||
316 | return -ENOMEM; | ||
317 | } | ||
318 | } | ||
319 | memcpy (urb->transfer_buffer, buf, len); | ||
320 | |||
321 | dr->bRequestType= BLUETOOTH_CONTROL_REQUEST_TYPE; | ||
322 | dr->bRequest = request; | ||
323 | dr->wValue = cpu_to_le16((u16) value); | ||
324 | dr->wIndex = cpu_to_le16((u16) bluetooth->control_out_bInterfaceNum); | ||
325 | dr->wLength = cpu_to_le16((u16) len); | ||
326 | |||
327 | usb_fill_control_urb (urb, bluetooth->dev, usb_sndctrlpipe(bluetooth->dev, 0), | ||
328 | (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth); | ||
329 | |||
330 | /* send it down the pipe */ | ||
331 | status = usb_submit_urb(urb, GFP_KERNEL); | ||
332 | if (status) | ||
333 | dbg("%s - usb_submit_urb(control) failed with status = %d", __FUNCTION__, status); | ||
334 | |||
335 | return status; | ||
336 | } | ||
337 | |||
338 | |||
339 | |||
340 | |||
341 | |||
342 | /***************************************************************************** | ||
343 | * Driver tty interface functions | ||
344 | *****************************************************************************/ | ||
345 | static int bluetooth_open (struct tty_struct *tty, struct file * filp) | ||
346 | { | ||
347 | struct usb_bluetooth *bluetooth; | ||
348 | int result; | ||
349 | |||
350 | dbg("%s", __FUNCTION__); | ||
351 | |||
352 | /* initialize the pointer incase something fails */ | ||
353 | tty->driver_data = NULL; | ||
354 | |||
355 | /* get the bluetooth object associated with this tty pointer */ | ||
356 | bluetooth = get_bluetooth_by_index (tty->index); | ||
357 | |||
358 | if (bluetooth_paranoia_check (bluetooth, __FUNCTION__)) { | ||
359 | return -ENODEV; | ||
360 | } | ||
361 | |||
362 | down (&bluetooth->lock); | ||
363 | |||
364 | ++bluetooth->open_count; | ||
365 | if (bluetooth->open_count == 1) { | ||
366 | /* set up our structure making the tty driver remember our object, and us it */ | ||
367 | tty->driver_data = bluetooth; | ||
368 | bluetooth->tty = tty; | ||
369 | |||
370 | /* force low_latency on so that our tty_push actually forces the data through, | ||
371 | * otherwise it is scheduled, and with high data rates (like with OHCI) data | ||
372 | * can get lost. */ | ||
373 | bluetooth->tty->low_latency = 1; | ||
374 | |||
375 | /* Reset the packet position counters */ | ||
376 | bluetooth->int_packet_pos = 0; | ||
377 | bluetooth->bulk_packet_pos = 0; | ||
378 | |||
379 | #ifndef BTBUGGYHARDWARE | ||
380 | /* Start reading from the device */ | ||
381 | usb_fill_bulk_urb (bluetooth->read_urb, bluetooth->dev, | ||
382 | usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), | ||
383 | bluetooth->bulk_in_buffer, | ||
384 | bluetooth->bulk_in_buffer_size, | ||
385 | bluetooth_read_bulk_callback, bluetooth); | ||
386 | result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); | ||
387 | if (result) | ||
388 | dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result); | ||
389 | #endif | ||
390 | usb_fill_int_urb (bluetooth->interrupt_in_urb, bluetooth->dev, | ||
391 | usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), | ||
392 | bluetooth->interrupt_in_buffer, | ||
393 | bluetooth->interrupt_in_buffer_size, | ||
394 | bluetooth_int_callback, bluetooth, | ||
395 | bluetooth->interrupt_in_interval); | ||
396 | result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL); | ||
397 | if (result) | ||
398 | dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result); | ||
399 | } | ||
400 | |||
401 | up(&bluetooth->lock); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | |||
407 | static void bluetooth_close (struct tty_struct *tty, struct file * filp) | ||
408 | { | ||
409 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
410 | |||
411 | if (!bluetooth) { | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | dbg("%s", __FUNCTION__); | ||
416 | |||
417 | if (!bluetooth->open_count) { | ||
418 | dbg ("%s - device not opened", __FUNCTION__); | ||
419 | return; | ||
420 | } | ||
421 | |||
422 | down (&bluetooth->lock); | ||
423 | |||
424 | --bluetooth->open_count; | ||
425 | if (bluetooth->open_count <= 0) { | ||
426 | bluetooth->open_count = 0; | ||
427 | |||
428 | /* shutdown any in-flight urbs that we know about */ | ||
429 | usb_kill_urb (bluetooth->read_urb); | ||
430 | usb_kill_urb (bluetooth->interrupt_in_urb); | ||
431 | } | ||
432 | up(&bluetooth->lock); | ||
433 | } | ||
434 | |||
435 | |||
436 | static int bluetooth_write (struct tty_struct * tty, const unsigned char *buf, int count) | ||
437 | { | ||
438 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
439 | struct urb *urb = NULL; | ||
440 | unsigned char *temp_buffer = NULL; | ||
441 | const unsigned char *current_buffer; | ||
442 | unsigned char *urb_buffer; | ||
443 | int i; | ||
444 | int retval = 0; | ||
445 | |||
446 | if (!bluetooth) { | ||
447 | return -ENODEV; | ||
448 | } | ||
449 | |||
450 | dbg("%s - %d byte(s)", __FUNCTION__, count); | ||
451 | |||
452 | if (!bluetooth->open_count) { | ||
453 | dbg ("%s - device not opened", __FUNCTION__); | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | |||
457 | if (count == 0) { | ||
458 | dbg("%s - write request of 0 bytes", __FUNCTION__); | ||
459 | return 0; | ||
460 | } | ||
461 | if (count == 1) { | ||
462 | dbg("%s - write request only included type %d", __FUNCTION__, buf[0]); | ||
463 | return 1; | ||
464 | } | ||
465 | |||
466 | #ifdef DEBUG | ||
467 | printk (KERN_DEBUG __FILE__ ": %s - length = %d, data = ", __FUNCTION__, count); | ||
468 | for (i = 0; i < count; ++i) { | ||
469 | printk ("%.2x ", buf[i]); | ||
470 | } | ||
471 | printk ("\n"); | ||
472 | #endif | ||
473 | |||
474 | current_buffer = buf; | ||
475 | |||
476 | switch (*current_buffer) { | ||
477 | /* First byte indicates the type of packet */ | ||
478 | case CMD_PKT: | ||
479 | /* dbg("%s- Send cmd_pkt len:%d", __FUNCTION__, count);*/ | ||
480 | |||
481 | retval = bluetooth_ctrl_msg (bluetooth, 0x00, 0x00, ¤t_buffer[1], count-1); | ||
482 | if (retval) { | ||
483 | goto exit; | ||
484 | } | ||
485 | retval = count; | ||
486 | break; | ||
487 | |||
488 | case ACL_PKT: | ||
489 | ++current_buffer; | ||
490 | --count; | ||
491 | |||
492 | urb_buffer = kmalloc (count, GFP_ATOMIC); | ||
493 | if (!urb_buffer) { | ||
494 | dev_err(&bluetooth->dev->dev, "out of memory\n"); | ||
495 | retval = -ENOMEM; | ||
496 | goto exit; | ||
497 | } | ||
498 | |||
499 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
500 | if (!urb) { | ||
501 | dev_err(&bluetooth->dev->dev, "no more free urbs\n"); | ||
502 | kfree(urb_buffer); | ||
503 | retval = -ENOMEM; | ||
504 | goto exit; | ||
505 | } | ||
506 | memcpy (urb_buffer, current_buffer, count); | ||
507 | |||
508 | /* build up our urb */ | ||
509 | usb_fill_bulk_urb(urb, bluetooth->dev, | ||
510 | usb_sndbulkpipe(bluetooth->dev, | ||
511 | bluetooth->bulk_out_endpointAddress), | ||
512 | urb_buffer, | ||
513 | count, | ||
514 | bluetooth_write_bulk_callback, | ||
515 | bluetooth); | ||
516 | |||
517 | |||
518 | /* send it down the pipe */ | ||
519 | retval = usb_submit_urb(urb, GFP_KERNEL); | ||
520 | if (retval) { | ||
521 | dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, retval); | ||
522 | goto exit; | ||
523 | } | ||
524 | |||
525 | /* we are done with this urb, so let the host driver | ||
526 | * really free it when it is finished with it */ | ||
527 | usb_free_urb (urb); | ||
528 | retval = count + 1; | ||
529 | break; | ||
530 | |||
531 | default : | ||
532 | dbg("%s - unsupported (at this time) write type", __FUNCTION__); | ||
533 | retval = -EINVAL; | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | exit: | ||
538 | kfree(temp_buffer); | ||
539 | |||
540 | return retval; | ||
541 | } | ||
542 | |||
543 | |||
544 | static int bluetooth_write_room (struct tty_struct *tty) | ||
545 | { | ||
546 | dbg("%s", __FUNCTION__); | ||
547 | |||
548 | /* | ||
549 | * We really can take anything the user throws at us | ||
550 | * but let's pick a nice big number to tell the tty | ||
551 | * layer that we have lots of free space | ||
552 | */ | ||
553 | return 2048; | ||
554 | } | ||
555 | |||
556 | |||
557 | static int bluetooth_chars_in_buffer (struct tty_struct *tty) | ||
558 | { | ||
559 | dbg("%s", __FUNCTION__); | ||
560 | |||
561 | /* | ||
562 | * We can't really account for how much data we | ||
563 | * have sent out, but hasn't made it through to the | ||
564 | * device, so just tell the tty layer that everything | ||
565 | * is flushed. | ||
566 | */ | ||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | |||
571 | static void bluetooth_throttle (struct tty_struct * tty) | ||
572 | { | ||
573 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
574 | |||
575 | if (!bluetooth) { | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | dbg("%s", __FUNCTION__); | ||
580 | |||
581 | if (!bluetooth->open_count) { | ||
582 | dbg ("%s - device not open", __FUNCTION__); | ||
583 | return; | ||
584 | } | ||
585 | |||
586 | dbg("%s unsupported (at this time)", __FUNCTION__); | ||
587 | |||
588 | return; | ||
589 | } | ||
590 | |||
591 | |||
592 | static void bluetooth_unthrottle (struct tty_struct * tty) | ||
593 | { | ||
594 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
595 | |||
596 | if (!bluetooth) { | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | dbg("%s", __FUNCTION__); | ||
601 | |||
602 | if (!bluetooth->open_count) { | ||
603 | dbg ("%s - device not open", __FUNCTION__); | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | dbg("%s unsupported (at this time)", __FUNCTION__); | ||
608 | } | ||
609 | |||
610 | |||
611 | static int bluetooth_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) | ||
612 | { | ||
613 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
614 | |||
615 | if (!bluetooth) { | ||
616 | return -ENODEV; | ||
617 | } | ||
618 | |||
619 | dbg("%s - cmd 0x%.4x", __FUNCTION__, cmd); | ||
620 | |||
621 | if (!bluetooth->open_count) { | ||
622 | dbg ("%s - device not open", __FUNCTION__); | ||
623 | return -ENODEV; | ||
624 | } | ||
625 | |||
626 | /* FIXME!!! */ | ||
627 | return -ENOIOCTLCMD; | ||
628 | } | ||
629 | |||
630 | |||
631 | static void bluetooth_set_termios (struct tty_struct *tty, struct termios * old) | ||
632 | { | ||
633 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
634 | |||
635 | if (!bluetooth) { | ||
636 | return; | ||
637 | } | ||
638 | |||
639 | dbg("%s", __FUNCTION__); | ||
640 | |||
641 | if (!bluetooth->open_count) { | ||
642 | dbg ("%s - device not open", __FUNCTION__); | ||
643 | return; | ||
644 | } | ||
645 | |||
646 | /* FIXME!!! */ | ||
647 | |||
648 | return; | ||
649 | } | ||
650 | |||
651 | |||
652 | #ifdef BTBUGGYHARDWARE | ||
653 | void btusb_enable_bulk_read(struct tty_struct *tty){ | ||
654 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
655 | int result; | ||
656 | |||
657 | if (!bluetooth) { | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | dbg("%s", __FUNCTION__); | ||
662 | |||
663 | if (!bluetooth->open_count) { | ||
664 | dbg ("%s - device not open", __FUNCTION__); | ||
665 | return; | ||
666 | } | ||
667 | |||
668 | if (bluetooth->read_urb) { | ||
669 | usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, | ||
670 | usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), | ||
671 | bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, | ||
672 | bluetooth_read_bulk_callback, bluetooth); | ||
673 | result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); | ||
674 | if (result) | ||
675 | err ("%s - failed submitting read urb, error %d", __FUNCTION__, result); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | void btusb_disable_bulk_read(struct tty_struct *tty){ | ||
680 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)tty->driver_data, __FUNCTION__); | ||
681 | |||
682 | if (!bluetooth) { | ||
683 | return; | ||
684 | } | ||
685 | |||
686 | dbg("%s", __FUNCTION__); | ||
687 | |||
688 | if (!bluetooth->open_count) { | ||
689 | dbg ("%s - device not open", __FUNCTION__); | ||
690 | return; | ||
691 | } | ||
692 | |||
693 | if ((bluetooth->read_urb) && (bluetooth->read_urb->actual_length)) | ||
694 | usb_kill_urb(bluetooth->read_urb); | ||
695 | } | ||
696 | #endif | ||
697 | |||
698 | |||
699 | /***************************************************************************** | ||
700 | * urb callback functions | ||
701 | *****************************************************************************/ | ||
702 | |||
703 | |||
704 | static void bluetooth_int_callback (struct urb *urb, struct pt_regs *regs) | ||
705 | { | ||
706 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); | ||
707 | unsigned char *data = urb->transfer_buffer; | ||
708 | unsigned int i; | ||
709 | unsigned int count = urb->actual_length; | ||
710 | unsigned int packet_size; | ||
711 | int status; | ||
712 | |||
713 | dbg("%s", __FUNCTION__); | ||
714 | |||
715 | if (!bluetooth) { | ||
716 | dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); | ||
717 | return; | ||
718 | } | ||
719 | |||
720 | switch (urb->status) { | ||
721 | case 0: | ||
722 | /* success */ | ||
723 | break; | ||
724 | case -ECONNRESET: | ||
725 | case -ENOENT: | ||
726 | case -ESHUTDOWN: | ||
727 | /* this urb is terminated, clean up */ | ||
728 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | ||
729 | return; | ||
730 | default: | ||
731 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | ||
732 | goto exit; | ||
733 | } | ||
734 | |||
735 | if (!count) { | ||
736 | dbg("%s - zero length int", __FUNCTION__); | ||
737 | goto exit; | ||
738 | } | ||
739 | |||
740 | |||
741 | #ifdef DEBUG | ||
742 | if (count) { | ||
743 | printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count); | ||
744 | for (i = 0; i < count; ++i) { | ||
745 | printk ("%.2x ", data[i]); | ||
746 | } | ||
747 | printk ("\n"); | ||
748 | } | ||
749 | #endif | ||
750 | |||
751 | #ifdef BTBUGGYHARDWARE | ||
752 | if ((count >= 2) && (data[0] == 0xFF) && (data[1] == 0x00)) { | ||
753 | data += 2; | ||
754 | count -= 2; | ||
755 | } | ||
756 | if (count == 0) { | ||
757 | urb->actual_length = 0; | ||
758 | goto exit; | ||
759 | } | ||
760 | #endif | ||
761 | /* We add a packet type identifier to the beginning of each | ||
762 | HCI frame. This makes the data in the tty look like a | ||
763 | serial USB devices. Each HCI frame can be broken across | ||
764 | multiple URBs so we buffer them until we have a full hci | ||
765 | packet */ | ||
766 | |||
767 | if (!bluetooth->int_packet_pos) { | ||
768 | bluetooth->int_buffer[0] = EVENT_PKT; | ||
769 | bluetooth->int_packet_pos++; | ||
770 | } | ||
771 | |||
772 | if (bluetooth->int_packet_pos + count > EVENT_BUFFER_SIZE) { | ||
773 | err("%s - exceeded EVENT_BUFFER_SIZE", __FUNCTION__); | ||
774 | bluetooth->int_packet_pos = 0; | ||
775 | goto exit; | ||
776 | } | ||
777 | |||
778 | memcpy (&bluetooth->int_buffer[bluetooth->int_packet_pos], | ||
779 | urb->transfer_buffer, count); | ||
780 | bluetooth->int_packet_pos += count; | ||
781 | urb->actual_length = 0; | ||
782 | |||
783 | if (bluetooth->int_packet_pos >= EVENT_HDR_SIZE) | ||
784 | packet_size = bluetooth->int_buffer[2]; | ||
785 | else | ||
786 | goto exit; | ||
787 | |||
788 | if (packet_size + EVENT_HDR_SIZE < bluetooth->int_packet_pos) { | ||
789 | err("%s - packet was too long", __FUNCTION__); | ||
790 | bluetooth->int_packet_pos = 0; | ||
791 | goto exit; | ||
792 | } | ||
793 | |||
794 | if (packet_size + EVENT_HDR_SIZE == bluetooth->int_packet_pos) { | ||
795 | for (i = 0; i < bluetooth->int_packet_pos; ++i) { | ||
796 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them */ | ||
797 | if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
798 | tty_flip_buffer_push(bluetooth->tty); | ||
799 | } | ||
800 | tty_insert_flip_char(bluetooth->tty, bluetooth->int_buffer[i], 0); | ||
801 | } | ||
802 | tty_flip_buffer_push(bluetooth->tty); | ||
803 | |||
804 | bluetooth->int_packet_pos = 0; | ||
805 | } | ||
806 | |||
807 | exit: | ||
808 | status = usb_submit_urb (urb, GFP_ATOMIC); | ||
809 | if (status) | ||
810 | err ("%s - usb_submit_urb failed with result %d", | ||
811 | __FUNCTION__, status); | ||
812 | } | ||
813 | |||
814 | |||
815 | static void bluetooth_ctrl_callback (struct urb *urb, struct pt_regs *regs) | ||
816 | { | ||
817 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); | ||
818 | |||
819 | dbg("%s", __FUNCTION__); | ||
820 | |||
821 | if (!bluetooth) { | ||
822 | dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); | ||
823 | return; | ||
824 | } | ||
825 | |||
826 | if (urb->status) { | ||
827 | dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); | ||
828 | return; | ||
829 | } | ||
830 | } | ||
831 | |||
832 | |||
833 | static void bluetooth_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | ||
834 | { | ||
835 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); | ||
836 | unsigned char *data = urb->transfer_buffer; | ||
837 | unsigned int count = urb->actual_length; | ||
838 | unsigned int i; | ||
839 | unsigned int packet_size; | ||
840 | int result; | ||
841 | |||
842 | |||
843 | dbg("%s", __FUNCTION__); | ||
844 | |||
845 | if (!bluetooth) { | ||
846 | dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); | ||
847 | return; | ||
848 | } | ||
849 | |||
850 | if (urb->status) { | ||
851 | dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); | ||
852 | if (urb->status == -ENOENT) { | ||
853 | dbg("%s - URB canceled, won't reschedule", __FUNCTION__); | ||
854 | return; | ||
855 | } | ||
856 | goto exit; | ||
857 | } | ||
858 | |||
859 | if (!count) { | ||
860 | dbg("%s - zero length read bulk", __FUNCTION__); | ||
861 | goto exit; | ||
862 | } | ||
863 | |||
864 | #ifdef DEBUG | ||
865 | if (count) { | ||
866 | printk (KERN_DEBUG __FILE__ ": %s- length = %d, data = ", __FUNCTION__, count); | ||
867 | for (i = 0; i < count; ++i) { | ||
868 | printk ("%.2x ", data[i]); | ||
869 | } | ||
870 | printk ("\n"); | ||
871 | } | ||
872 | #endif | ||
873 | #ifdef BTBUGGYHARDWARE | ||
874 | if ((count == 4) && (data[0] == 0x00) && (data[1] == 0x00) | ||
875 | && (data[2] == 0x00) && (data[3] == 0x00)) { | ||
876 | urb->actual_length = 0; | ||
877 | usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, | ||
878 | usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), | ||
879 | bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, | ||
880 | bluetooth_read_bulk_callback, bluetooth); | ||
881 | result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); | ||
882 | if (result) | ||
883 | err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); | ||
884 | |||
885 | return; | ||
886 | } | ||
887 | #endif | ||
888 | /* We add a packet type identifier to the beginning of each | ||
889 | HCI frame. This makes the data in the tty look like a | ||
890 | serial USB devices. Each HCI frame can be broken across | ||
891 | multiple URBs so we buffer them until we have a full hci | ||
892 | packet */ | ||
893 | |||
894 | if (!bluetooth->bulk_packet_pos) { | ||
895 | bluetooth->bulk_buffer[0] = ACL_PKT; | ||
896 | bluetooth->bulk_packet_pos++; | ||
897 | } | ||
898 | |||
899 | if (bluetooth->bulk_packet_pos + count > ACL_BUFFER_SIZE) { | ||
900 | err("%s - exceeded ACL_BUFFER_SIZE", __FUNCTION__); | ||
901 | bluetooth->bulk_packet_pos = 0; | ||
902 | goto exit; | ||
903 | } | ||
904 | |||
905 | memcpy (&bluetooth->bulk_buffer[bluetooth->bulk_packet_pos], | ||
906 | urb->transfer_buffer, count); | ||
907 | bluetooth->bulk_packet_pos += count; | ||
908 | urb->actual_length = 0; | ||
909 | |||
910 | if (bluetooth->bulk_packet_pos >= ACL_HDR_SIZE) { | ||
911 | packet_size = CHAR2INT16(bluetooth->bulk_buffer[4],bluetooth->bulk_buffer[3]); | ||
912 | } else { | ||
913 | goto exit; | ||
914 | } | ||
915 | |||
916 | if (packet_size + ACL_HDR_SIZE < bluetooth->bulk_packet_pos) { | ||
917 | err("%s - packet was too long", __FUNCTION__); | ||
918 | bluetooth->bulk_packet_pos = 0; | ||
919 | goto exit; | ||
920 | } | ||
921 | |||
922 | if (packet_size + ACL_HDR_SIZE == bluetooth->bulk_packet_pos) { | ||
923 | for (i = 0; i < bluetooth->bulk_packet_pos; ++i) { | ||
924 | /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ | ||
925 | if (bluetooth->tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
926 | tty_flip_buffer_push(bluetooth->tty); | ||
927 | } | ||
928 | tty_insert_flip_char(bluetooth->tty, bluetooth->bulk_buffer[i], 0); | ||
929 | } | ||
930 | tty_flip_buffer_push(bluetooth->tty); | ||
931 | bluetooth->bulk_packet_pos = 0; | ||
932 | } | ||
933 | |||
934 | exit: | ||
935 | if (!bluetooth || !bluetooth->open_count) | ||
936 | return; | ||
937 | |||
938 | usb_fill_bulk_urb(bluetooth->read_urb, bluetooth->dev, | ||
939 | usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), | ||
940 | bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, | ||
941 | bluetooth_read_bulk_callback, bluetooth); | ||
942 | result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL); | ||
943 | if (result) | ||
944 | err ("%s - failed resubmitting read urb, error %d", __FUNCTION__, result); | ||
945 | |||
946 | return; | ||
947 | } | ||
948 | |||
949 | |||
950 | static void bluetooth_write_bulk_callback (struct urb *urb, struct pt_regs *regs) | ||
951 | { | ||
952 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)urb->context, __FUNCTION__); | ||
953 | |||
954 | dbg("%s", __FUNCTION__); | ||
955 | |||
956 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
957 | kfree(urb->transfer_buffer); | ||
958 | |||
959 | if (!bluetooth) { | ||
960 | dbg("%s - bad bluetooth pointer, exiting", __FUNCTION__); | ||
961 | return; | ||
962 | } | ||
963 | |||
964 | if (urb->status) { | ||
965 | dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); | ||
966 | return; | ||
967 | } | ||
968 | |||
969 | /* wake up our little function to let the tty layer know that something happened */ | ||
970 | schedule_work(&bluetooth->work); | ||
971 | } | ||
972 | |||
973 | |||
974 | static void bluetooth_softint(void *private) | ||
975 | { | ||
976 | struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__); | ||
977 | |||
978 | dbg("%s", __FUNCTION__); | ||
979 | |||
980 | if (!bluetooth) | ||
981 | return; | ||
982 | |||
983 | tty_wakeup(bluetooth->tty); | ||
984 | } | ||
985 | |||
986 | |||
987 | static int usb_bluetooth_probe (struct usb_interface *intf, | ||
988 | const struct usb_device_id *id) | ||
989 | { | ||
990 | struct usb_device *dev = interface_to_usbdev (intf); | ||
991 | struct usb_bluetooth *bluetooth = NULL; | ||
992 | struct usb_host_interface *interface; | ||
993 | struct usb_endpoint_descriptor *endpoint; | ||
994 | struct usb_endpoint_descriptor *interrupt_in_endpoint[8]; | ||
995 | struct usb_endpoint_descriptor *bulk_in_endpoint[8]; | ||
996 | struct usb_endpoint_descriptor *bulk_out_endpoint[8]; | ||
997 | int control_out_endpoint; | ||
998 | |||
999 | int minor; | ||
1000 | int buffer_size; | ||
1001 | int i; | ||
1002 | int num_interrupt_in = 0; | ||
1003 | int num_bulk_in = 0; | ||
1004 | int num_bulk_out = 0; | ||
1005 | |||
1006 | interface = intf->cur_altsetting; | ||
1007 | control_out_endpoint = interface->desc.bInterfaceNumber; | ||
1008 | |||
1009 | /* find the endpoints that we need */ | ||
1010 | for (i = 0; i < interface->desc.bNumEndpoints; ++i) { | ||
1011 | endpoint = &interface->endpoint[i].desc; | ||
1012 | |||
1013 | if ((endpoint->bEndpointAddress & 0x80) && | ||
1014 | ((endpoint->bmAttributes & 3) == 0x02)) { | ||
1015 | /* we found a bulk in endpoint */ | ||
1016 | dbg("found bulk in"); | ||
1017 | bulk_in_endpoint[num_bulk_in] = endpoint; | ||
1018 | ++num_bulk_in; | ||
1019 | } | ||
1020 | |||
1021 | if (((endpoint->bEndpointAddress & 0x80) == 0x00) && | ||
1022 | ((endpoint->bmAttributes & 3) == 0x02)) { | ||
1023 | /* we found a bulk out endpoint */ | ||
1024 | dbg("found bulk out"); | ||
1025 | bulk_out_endpoint[num_bulk_out] = endpoint; | ||
1026 | ++num_bulk_out; | ||
1027 | } | ||
1028 | |||
1029 | if ((endpoint->bEndpointAddress & 0x80) && | ||
1030 | ((endpoint->bmAttributes & 3) == 0x03)) { | ||
1031 | /* we found a interrupt in endpoint */ | ||
1032 | dbg("found interrupt in"); | ||
1033 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | ||
1034 | ++num_interrupt_in; | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | /* according to the spec, we can only have 1 bulk_in, 1 bulk_out, and 1 interrupt_in endpoints */ | ||
1039 | if ((num_bulk_in != 1) || | ||
1040 | (num_bulk_out != 1) || | ||
1041 | (num_interrupt_in != 1)) { | ||
1042 | dbg ("%s - improper number of endpoints. Bluetooth driver not bound.", __FUNCTION__); | ||
1043 | return -EIO; | ||
1044 | } | ||
1045 | |||
1046 | info("USB Bluetooth converter detected"); | ||
1047 | |||
1048 | for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor) | ||
1049 | ; | ||
1050 | if (bluetooth_table[minor]) { | ||
1051 | err("No more free Bluetooth devices"); | ||
1052 | return -ENODEV; | ||
1053 | } | ||
1054 | |||
1055 | if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) { | ||
1056 | err("Out of memory"); | ||
1057 | return -ENOMEM; | ||
1058 | } | ||
1059 | |||
1060 | memset(bluetooth, 0, sizeof(struct usb_bluetooth)); | ||
1061 | |||
1062 | bluetooth->magic = USB_BLUETOOTH_MAGIC; | ||
1063 | bluetooth->dev = dev; | ||
1064 | bluetooth->minor = minor; | ||
1065 | INIT_WORK(&bluetooth->work, bluetooth_softint, bluetooth); | ||
1066 | init_MUTEX(&bluetooth->lock); | ||
1067 | |||
1068 | /* record the interface number for the control out */ | ||
1069 | bluetooth->control_out_bInterfaceNum = control_out_endpoint; | ||
1070 | |||
1071 | /* create our control out urb pool */ | ||
1072 | for (i = 0; i < NUM_CONTROL_URBS; ++i) { | ||
1073 | struct urb *urb = usb_alloc_urb(0, GFP_KERNEL); | ||
1074 | if (urb == NULL) { | ||
1075 | err("No free urbs available"); | ||
1076 | goto probe_error; | ||
1077 | } | ||
1078 | urb->transfer_buffer = NULL; | ||
1079 | bluetooth->control_urb_pool[i] = urb; | ||
1080 | } | ||
1081 | |||
1082 | /* set up the endpoint information */ | ||
1083 | endpoint = bulk_in_endpoint[0]; | ||
1084 | bluetooth->read_urb = usb_alloc_urb (0, GFP_KERNEL); | ||
1085 | if (!bluetooth->read_urb) { | ||
1086 | err("No free urbs available"); | ||
1087 | goto probe_error; | ||
1088 | } | ||
1089 | bluetooth->bulk_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
1090 | bluetooth->bulk_in_endpointAddress = endpoint->bEndpointAddress; | ||
1091 | bluetooth->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); | ||
1092 | if (!bluetooth->bulk_in_buffer) { | ||
1093 | err("Couldn't allocate bulk_in_buffer"); | ||
1094 | goto probe_error; | ||
1095 | } | ||
1096 | usb_fill_bulk_urb(bluetooth->read_urb, dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), | ||
1097 | bluetooth->bulk_in_buffer, buffer_size, bluetooth_read_bulk_callback, bluetooth); | ||
1098 | |||
1099 | endpoint = bulk_out_endpoint[0]; | ||
1100 | bluetooth->bulk_out_endpointAddress = endpoint->bEndpointAddress; | ||
1101 | bluetooth->bulk_out_buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; | ||
1102 | |||
1103 | endpoint = interrupt_in_endpoint[0]; | ||
1104 | bluetooth->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
1105 | if (!bluetooth->interrupt_in_urb) { | ||
1106 | err("No free urbs available"); | ||
1107 | goto probe_error; | ||
1108 | } | ||
1109 | bluetooth->interrupt_in_buffer_size = buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
1110 | bluetooth->interrupt_in_endpointAddress = endpoint->bEndpointAddress; | ||
1111 | bluetooth->interrupt_in_interval = endpoint->bInterval; | ||
1112 | bluetooth->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL); | ||
1113 | if (!bluetooth->interrupt_in_buffer) { | ||
1114 | err("Couldn't allocate interrupt_in_buffer"); | ||
1115 | goto probe_error; | ||
1116 | } | ||
1117 | usb_fill_int_urb(bluetooth->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
1118 | bluetooth->interrupt_in_buffer, buffer_size, bluetooth_int_callback, | ||
1119 | bluetooth, endpoint->bInterval); | ||
1120 | |||
1121 | /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */ | ||
1122 | tty_register_device (bluetooth_tty_driver, minor, &intf->dev); | ||
1123 | info("Bluetooth converter now attached to ttyUB%d (or usb/ttub/%d for devfs)", minor, minor); | ||
1124 | |||
1125 | bluetooth_table[minor] = bluetooth; | ||
1126 | |||
1127 | /* success */ | ||
1128 | usb_set_intfdata (intf, bluetooth); | ||
1129 | return 0; | ||
1130 | |||
1131 | probe_error: | ||
1132 | if (bluetooth->read_urb) | ||
1133 | usb_free_urb (bluetooth->read_urb); | ||
1134 | if (bluetooth->bulk_in_buffer) | ||
1135 | kfree (bluetooth->bulk_in_buffer); | ||
1136 | if (bluetooth->interrupt_in_urb) | ||
1137 | usb_free_urb (bluetooth->interrupt_in_urb); | ||
1138 | if (bluetooth->interrupt_in_buffer) | ||
1139 | kfree (bluetooth->interrupt_in_buffer); | ||
1140 | for (i = 0; i < NUM_CONTROL_URBS; ++i) | ||
1141 | if (bluetooth->control_urb_pool[i]) { | ||
1142 | if (bluetooth->control_urb_pool[i]->transfer_buffer) | ||
1143 | kfree (bluetooth->control_urb_pool[i]->transfer_buffer); | ||
1144 | usb_free_urb (bluetooth->control_urb_pool[i]); | ||
1145 | } | ||
1146 | |||
1147 | bluetooth_table[minor] = NULL; | ||
1148 | |||
1149 | /* free up any memory that we allocated */ | ||
1150 | kfree (bluetooth); | ||
1151 | return -EIO; | ||
1152 | } | ||
1153 | |||
1154 | |||
1155 | static void usb_bluetooth_disconnect(struct usb_interface *intf) | ||
1156 | { | ||
1157 | struct usb_bluetooth *bluetooth = usb_get_intfdata (intf); | ||
1158 | int i; | ||
1159 | |||
1160 | usb_set_intfdata (intf, NULL); | ||
1161 | if (bluetooth) { | ||
1162 | if ((bluetooth->open_count) && (bluetooth->tty)) | ||
1163 | tty_hangup(bluetooth->tty); | ||
1164 | |||
1165 | bluetooth->open_count = 0; | ||
1166 | |||
1167 | if (bluetooth->read_urb) { | ||
1168 | usb_kill_urb (bluetooth->read_urb); | ||
1169 | usb_free_urb (bluetooth->read_urb); | ||
1170 | } | ||
1171 | if (bluetooth->bulk_in_buffer) | ||
1172 | kfree (bluetooth->bulk_in_buffer); | ||
1173 | |||
1174 | if (bluetooth->interrupt_in_urb) { | ||
1175 | usb_kill_urb (bluetooth->interrupt_in_urb); | ||
1176 | usb_free_urb (bluetooth->interrupt_in_urb); | ||
1177 | } | ||
1178 | if (bluetooth->interrupt_in_buffer) | ||
1179 | kfree (bluetooth->interrupt_in_buffer); | ||
1180 | |||
1181 | tty_unregister_device (bluetooth_tty_driver, bluetooth->minor); | ||
1182 | |||
1183 | for (i = 0; i < NUM_CONTROL_URBS; ++i) { | ||
1184 | if (bluetooth->control_urb_pool[i]) { | ||
1185 | usb_kill_urb (bluetooth->control_urb_pool[i]); | ||
1186 | if (bluetooth->control_urb_pool[i]->transfer_buffer) | ||
1187 | kfree (bluetooth->control_urb_pool[i]->transfer_buffer); | ||
1188 | usb_free_urb (bluetooth->control_urb_pool[i]); | ||
1189 | } | ||
1190 | } | ||
1191 | |||
1192 | info("Bluetooth converter now disconnected from ttyUB%d", bluetooth->minor); | ||
1193 | |||
1194 | bluetooth_table[bluetooth->minor] = NULL; | ||
1195 | |||
1196 | /* free up any memory that we allocated */ | ||
1197 | kfree (bluetooth); | ||
1198 | } else { | ||
1199 | info("device disconnected"); | ||
1200 | } | ||
1201 | } | ||
1202 | |||
1203 | static struct tty_operations bluetooth_ops = { | ||
1204 | .open = bluetooth_open, | ||
1205 | .close = bluetooth_close, | ||
1206 | .write = bluetooth_write, | ||
1207 | .write_room = bluetooth_write_room, | ||
1208 | .ioctl = bluetooth_ioctl, | ||
1209 | .set_termios = bluetooth_set_termios, | ||
1210 | .throttle = bluetooth_throttle, | ||
1211 | .unthrottle = bluetooth_unthrottle, | ||
1212 | .chars_in_buffer = bluetooth_chars_in_buffer, | ||
1213 | }; | ||
1214 | |||
1215 | static int usb_bluetooth_init(void) | ||
1216 | { | ||
1217 | int i; | ||
1218 | int result; | ||
1219 | |||
1220 | /* Initialize our global data */ | ||
1221 | for (i = 0; i < BLUETOOTH_TTY_MINORS; ++i) { | ||
1222 | bluetooth_table[i] = NULL; | ||
1223 | } | ||
1224 | |||
1225 | info ("USB Bluetooth support registered"); | ||
1226 | |||
1227 | bluetooth_tty_driver = alloc_tty_driver(BLUETOOTH_TTY_MINORS); | ||
1228 | if (!bluetooth_tty_driver) | ||
1229 | return -ENOMEM; | ||
1230 | |||
1231 | bluetooth_tty_driver->owner = THIS_MODULE; | ||
1232 | bluetooth_tty_driver->driver_name = "usb-bluetooth"; | ||
1233 | bluetooth_tty_driver->name = "ttyUB"; | ||
1234 | bluetooth_tty_driver->devfs_name = "usb/ttub/"; | ||
1235 | bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR; | ||
1236 | bluetooth_tty_driver->minor_start = 0; | ||
1237 | bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1238 | bluetooth_tty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1239 | bluetooth_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; | ||
1240 | bluetooth_tty_driver->init_termios = tty_std_termios; | ||
1241 | bluetooth_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
1242 | tty_set_operations(bluetooth_tty_driver, &bluetooth_ops); | ||
1243 | if (tty_register_driver (bluetooth_tty_driver)) { | ||
1244 | err("%s - failed to register tty driver", __FUNCTION__); | ||
1245 | put_tty_driver(bluetooth_tty_driver); | ||
1246 | return -1; | ||
1247 | } | ||
1248 | |||
1249 | /* register the USB driver */ | ||
1250 | result = usb_register(&usb_bluetooth_driver); | ||
1251 | if (result < 0) { | ||
1252 | tty_unregister_driver(bluetooth_tty_driver); | ||
1253 | put_tty_driver(bluetooth_tty_driver); | ||
1254 | err("usb_register failed for the USB bluetooth driver. Error number %d", result); | ||
1255 | return -1; | ||
1256 | } | ||
1257 | |||
1258 | info(DRIVER_DESC " " DRIVER_VERSION); | ||
1259 | |||
1260 | return 0; | ||
1261 | } | ||
1262 | |||
1263 | |||
1264 | static void usb_bluetooth_exit(void) | ||
1265 | { | ||
1266 | usb_deregister(&usb_bluetooth_driver); | ||
1267 | tty_unregister_driver(bluetooth_tty_driver); | ||
1268 | put_tty_driver(bluetooth_tty_driver); | ||
1269 | } | ||
1270 | |||
1271 | |||
1272 | module_init(usb_bluetooth_init); | ||
1273 | module_exit(usb_bluetooth_exit); | ||
1274 | |||
1275 | /* Module information */ | ||
1276 | MODULE_AUTHOR( DRIVER_AUTHOR ); | ||
1277 | MODULE_DESCRIPTION( DRIVER_DESC ); | ||
1278 | MODULE_LICENSE("GPL"); | ||
1279 | |||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 16ecad30e29c..1b4751412970 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -827,11 +827,10 @@ skip_normal_probe: | |||
827 | return -ENODEV; | 827 | return -ENODEV; |
828 | } | 828 | } |
829 | 829 | ||
830 | if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) { | 830 | if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { |
831 | dev_dbg(&intf->dev, "out of memory (acm kmalloc)\n"); | 831 | dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); |
832 | goto alloc_fail; | 832 | goto alloc_fail; |
833 | } | 833 | } |
834 | memset(acm, 0, sizeof(struct acm)); | ||
835 | 834 | ||
836 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); | 835 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); |
837 | readsize = le16_to_cpu(epread->wMaxPacketSize); | 836 | readsize = le16_to_cpu(epread->wMaxPacketSize); |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index e195709c9c7f..357e75335f17 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -844,9 +844,8 @@ static struct file_operations usblp_fops = { | |||
844 | }; | 844 | }; |
845 | 845 | ||
846 | static struct usb_class_driver usblp_class = { | 846 | static struct usb_class_driver usblp_class = { |
847 | .name = "usb/lp%d", | 847 | .name = "lp%d", |
848 | .fops = &usblp_fops, | 848 | .fops = &usblp_fops, |
849 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, | ||
850 | .minor_base = USBLP_MINOR_BASE, | 849 | .minor_base = USBLP_MINOR_BASE, |
851 | }; | 850 | }; |
852 | 851 | ||
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 1a9ff6184943..ff03184da403 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -61,14 +61,17 @@ config USB_DYNAMIC_MINORS | |||
61 | If you are unsure about this, say N here. | 61 | If you are unsure about this, say N here. |
62 | 62 | ||
63 | config USB_SUSPEND | 63 | config USB_SUSPEND |
64 | bool "USB suspend/resume (EXPERIMENTAL)" | 64 | bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)" |
65 | depends on USB && PM && EXPERIMENTAL | 65 | depends on USB && PM && EXPERIMENTAL |
66 | help | 66 | help |
67 | If you say Y here, you can use driver calls or the sysfs | 67 | If you say Y here, you can use driver calls or the sysfs |
68 | "power/state" file to suspend or resume individual USB | 68 | "power/state" file to suspend or resume individual USB |
69 | peripherals. There are many related features, such as | 69 | peripherals. |
70 | remote wakeup and driver-specific suspend processing, that | 70 | |
71 | may not yet work as expected. | 71 | Also, USB "remote wakeup" signaling is supported, whereby some |
72 | USB devices (like keyboards and network adapters) can wake up | ||
73 | their parent hub. That wakeup cascades up the USB tree, and | ||
74 | could wake the system from states like suspend-to-RAM. | ||
72 | 75 | ||
73 | If you are unsure about this, say N here. | 76 | If you are unsure about this, say N here. |
74 | 77 | ||
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index d5503cf0bf74..dd1c4d2a0c31 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ |
6 | config.o file.o buffer.o sysfs.o devio.o | 6 | config.o file.o buffer.o sysfs.o devio.o notify.o |
7 | 7 | ||
8 | ifeq ($(CONFIG_PCI),y) | 8 | ifeq ($(CONFIG_PCI),y) |
9 | usbcore-objs += hcd-pci.o | 9 | usbcore-objs += hcd-pci.o |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 99595e07b653..993019500cc3 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -112,8 +112,12 @@ void usb_release_interface_cache(struct kref *ref) | |||
112 | struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); | 112 | struct usb_interface_cache *intfc = ref_to_usb_interface_cache(ref); |
113 | int j; | 113 | int j; |
114 | 114 | ||
115 | for (j = 0; j < intfc->num_altsetting; j++) | 115 | for (j = 0; j < intfc->num_altsetting; j++) { |
116 | kfree(intfc->altsetting[j].endpoint); | 116 | struct usb_host_interface *alt = &intfc->altsetting[j]; |
117 | |||
118 | kfree(alt->endpoint); | ||
119 | kfree(alt->string); | ||
120 | } | ||
117 | kfree(intfc); | 121 | kfree(intfc); |
118 | } | 122 | } |
119 | 123 | ||
@@ -188,10 +192,9 @@ static int usb_parse_interface(struct device *ddev, int cfgno, | |||
188 | } | 192 | } |
189 | 193 | ||
190 | len = sizeof(struct usb_host_endpoint) * num_ep; | 194 | len = sizeof(struct usb_host_endpoint) * num_ep; |
191 | alt->endpoint = kmalloc(len, GFP_KERNEL); | 195 | alt->endpoint = kzalloc(len, GFP_KERNEL); |
192 | if (!alt->endpoint) | 196 | if (!alt->endpoint) |
193 | return -ENOMEM; | 197 | return -ENOMEM; |
194 | memset(alt->endpoint, 0, len); | ||
195 | 198 | ||
196 | /* Parse all the endpoint descriptors */ | 199 | /* Parse all the endpoint descriptors */ |
197 | n = 0; | 200 | n = 0; |
@@ -353,10 +356,9 @@ static int usb_parse_configuration(struct device *ddev, int cfgidx, | |||
353 | } | 356 | } |
354 | 357 | ||
355 | len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j; | 358 | len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j; |
356 | config->intf_cache[i] = intfc = kmalloc(len, GFP_KERNEL); | 359 | config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL); |
357 | if (!intfc) | 360 | if (!intfc) |
358 | return -ENOMEM; | 361 | return -ENOMEM; |
359 | memset(intfc, 0, len); | ||
360 | kref_init(&intfc->ref); | 362 | kref_init(&intfc->ref); |
361 | } | 363 | } |
362 | 364 | ||
@@ -422,8 +424,6 @@ void usb_destroy_configuration(struct usb_device *dev) | |||
422 | struct usb_host_config *cf = &dev->config[c]; | 424 | struct usb_host_config *cf = &dev->config[c]; |
423 | 425 | ||
424 | kfree(cf->string); | 426 | kfree(cf->string); |
425 | cf->string = NULL; | ||
426 | |||
427 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { | 427 | for (i = 0; i < cf->desc.bNumInterfaces; i++) { |
428 | if (cf->intf_cache[i]) | 428 | if (cf->intf_cache[i]) |
429 | kref_put(&cf->intf_cache[i]->ref, | 429 | kref_put(&cf->intf_cache[i]->ref, |
@@ -459,16 +459,14 @@ int usb_get_configuration(struct usb_device *dev) | |||
459 | } | 459 | } |
460 | 460 | ||
461 | length = ncfg * sizeof(struct usb_host_config); | 461 | length = ncfg * sizeof(struct usb_host_config); |
462 | dev->config = kmalloc(length, GFP_KERNEL); | 462 | dev->config = kzalloc(length, GFP_KERNEL); |
463 | if (!dev->config) | 463 | if (!dev->config) |
464 | goto err2; | 464 | goto err2; |
465 | memset(dev->config, 0, length); | ||
466 | 465 | ||
467 | length = ncfg * sizeof(char *); | 466 | length = ncfg * sizeof(char *); |
468 | dev->rawdescriptors = kmalloc(length, GFP_KERNEL); | 467 | dev->rawdescriptors = kzalloc(length, GFP_KERNEL); |
469 | if (!dev->rawdescriptors) | 468 | if (!dev->rawdescriptors) |
470 | goto err2; | 469 | goto err2; |
471 | memset(dev->rawdescriptors, 0, length); | ||
472 | 470 | ||
473 | buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); | 471 | buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); |
474 | if (!buffer) | 472 | if (!buffer) |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index befe0c7f63d1..942cd437dc48 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/usb.h> | 46 | #include <linux/usb.h> |
47 | #include <linux/usbdevice_fs.h> | 47 | #include <linux/usbdevice_fs.h> |
48 | #include <linux/cdev.h> | 48 | #include <linux/cdev.h> |
49 | #include <linux/notifier.h> | ||
49 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
50 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
51 | #include <linux/moduleparam.h> | 52 | #include <linux/moduleparam.h> |
@@ -209,10 +210,10 @@ err: | |||
209 | static struct async *alloc_async(unsigned int numisoframes) | 210 | static struct async *alloc_async(unsigned int numisoframes) |
210 | { | 211 | { |
211 | unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor); | 212 | unsigned int assize = sizeof(struct async) + numisoframes * sizeof(struct usb_iso_packet_descriptor); |
212 | struct async *as = kmalloc(assize, GFP_KERNEL); | 213 | struct async *as = kzalloc(assize, GFP_KERNEL); |
214 | |||
213 | if (!as) | 215 | if (!as) |
214 | return NULL; | 216 | return NULL; |
215 | memset(as, 0, assize); | ||
216 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); | 217 | as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); |
217 | if (!as->urb) { | 218 | if (!as->urb) { |
218 | kfree(as); | 219 | kfree(as); |
@@ -279,6 +280,28 @@ static inline struct async *async_getpending(struct dev_state *ps, void __user * | |||
279 | return NULL; | 280 | return NULL; |
280 | } | 281 | } |
281 | 282 | ||
283 | static void snoop_urb(struct urb *urb, void __user *userurb) | ||
284 | { | ||
285 | int j; | ||
286 | unsigned char *data = urb->transfer_buffer; | ||
287 | |||
288 | if (!usbfs_snoop) | ||
289 | return; | ||
290 | |||
291 | if (urb->pipe & USB_DIR_IN) | ||
292 | dev_info(&urb->dev->dev, "direction=IN\n"); | ||
293 | else | ||
294 | dev_info(&urb->dev->dev, "direction=OUT\n"); | ||
295 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | ||
296 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | ||
297 | urb->transfer_buffer_length); | ||
298 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | ||
299 | dev_info(&urb->dev->dev, "data: "); | ||
300 | for (j = 0; j < urb->transfer_buffer_length; ++j) | ||
301 | printk ("%02x ", data[j]); | ||
302 | printk("\n"); | ||
303 | } | ||
304 | |||
282 | static void async_completed(struct urb *urb, struct pt_regs *regs) | 305 | static void async_completed(struct urb *urb, struct pt_regs *regs) |
283 | { | 306 | { |
284 | struct async *as = (struct async *)urb->context; | 307 | struct async *as = (struct async *)urb->context; |
@@ -296,7 +319,9 @@ static void async_completed(struct urb *urb, struct pt_regs *regs) | |||
296 | kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 319 | kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, |
297 | as->euid); | 320 | as->euid); |
298 | } | 321 | } |
299 | wake_up(&ps->wait); | 322 | snoop(&urb->dev->dev, "urb complete\n"); |
323 | snoop_urb(urb, as->userurb); | ||
324 | wake_up(&ps->wait); | ||
300 | } | 325 | } |
301 | 326 | ||
302 | static void destroy_async (struct dev_state *ps, struct list_head *list) | 327 | static void destroy_async (struct dev_state *ps, struct list_head *list) |
@@ -493,6 +518,23 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
493 | return ret; | 518 | return ret; |
494 | } | 519 | } |
495 | 520 | ||
521 | static struct usb_device *usbdev_lookup_minor(int minor) | ||
522 | { | ||
523 | struct class_device *class_dev; | ||
524 | struct usb_device *dev = NULL; | ||
525 | |||
526 | down(&usb_device_class->sem); | ||
527 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | ||
528 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | ||
529 | dev = class_dev->class_data; | ||
530 | break; | ||
531 | } | ||
532 | } | ||
533 | up(&usb_device_class->sem); | ||
534 | |||
535 | return dev; | ||
536 | }; | ||
537 | |||
496 | /* | 538 | /* |
497 | * file operations | 539 | * file operations |
498 | */ | 540 | */ |
@@ -601,7 +643,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
601 | if (usbfs_snoop) { | 643 | if (usbfs_snoop) { |
602 | dev_info(&dev->dev, "control read: data "); | 644 | dev_info(&dev->dev, "control read: data "); |
603 | for (j = 0; j < i; ++j) | 645 | for (j = 0; j < i; ++j) |
604 | printk ("%02x ", (unsigned char)(tbuf)[j]); | 646 | printk("%02x ", (unsigned char)(tbuf)[j]); |
605 | printk("\n"); | 647 | printk("\n"); |
606 | } | 648 | } |
607 | if (copy_to_user(ctrl.data, tbuf, i)) { | 649 | if (copy_to_user(ctrl.data, tbuf, i)) { |
@@ -624,7 +666,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
624 | if (usbfs_snoop) { | 666 | if (usbfs_snoop) { |
625 | dev_info(&dev->dev, "control write: data: "); | 667 | dev_info(&dev->dev, "control write: data: "); |
626 | for (j = 0; j < ctrl.wLength; ++j) | 668 | for (j = 0; j < ctrl.wLength; ++j) |
627 | printk ("%02x ", (unsigned char)(tbuf)[j]); | 669 | printk("%02x ", (unsigned char)(tbuf)[j]); |
628 | printk("\n"); | 670 | printk("\n"); |
629 | } | 671 | } |
630 | usb_unlock_device(dev); | 672 | usb_unlock_device(dev); |
@@ -649,7 +691,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
649 | unsigned int tmo, len1, pipe; | 691 | unsigned int tmo, len1, pipe; |
650 | int len2; | 692 | int len2; |
651 | unsigned char *tbuf; | 693 | unsigned char *tbuf; |
652 | int i, ret; | 694 | int i, j, ret; |
653 | 695 | ||
654 | if (copy_from_user(&bulk, arg, sizeof(bulk))) | 696 | if (copy_from_user(&bulk, arg, sizeof(bulk))) |
655 | return -EFAULT; | 697 | return -EFAULT; |
@@ -674,10 +716,18 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
674 | kfree(tbuf); | 716 | kfree(tbuf); |
675 | return -EINVAL; | 717 | return -EINVAL; |
676 | } | 718 | } |
719 | snoop(&dev->dev, "bulk read: len=0x%02x timeout=%04d\n", | ||
720 | bulk.len, bulk.timeout); | ||
677 | usb_unlock_device(dev); | 721 | usb_unlock_device(dev); |
678 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 722 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
679 | usb_lock_device(dev); | 723 | usb_lock_device(dev); |
680 | if (!i && len2) { | 724 | if (!i && len2) { |
725 | if (usbfs_snoop) { | ||
726 | dev_info(&dev->dev, "bulk read: data "); | ||
727 | for (j = 0; j < len2; ++j) | ||
728 | printk("%02x ", (unsigned char)(tbuf)[j]); | ||
729 | printk("\n"); | ||
730 | } | ||
681 | if (copy_to_user(bulk.data, tbuf, len2)) { | 731 | if (copy_to_user(bulk.data, tbuf, len2)) { |
682 | kfree(tbuf); | 732 | kfree(tbuf); |
683 | return -EFAULT; | 733 | return -EFAULT; |
@@ -690,6 +740,14 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) | |||
690 | return -EFAULT; | 740 | return -EFAULT; |
691 | } | 741 | } |
692 | } | 742 | } |
743 | snoop(&dev->dev, "bulk write: len=0x%02x timeout=%04d\n", | ||
744 | bulk.len, bulk.timeout); | ||
745 | if (usbfs_snoop) { | ||
746 | dev_info(&dev->dev, "bulk write: data: "); | ||
747 | for (j = 0; j < len1; ++j) | ||
748 | printk("%02x ", (unsigned char)(tbuf)[j]); | ||
749 | printk("\n"); | ||
750 | } | ||
693 | usb_unlock_device(dev); | 751 | usb_unlock_device(dev); |
694 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); | 752 | i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); |
695 | usb_lock_device(dev); | 753 | usb_lock_device(dev); |
@@ -835,7 +893,6 @@ static int proc_setconfig(struct dev_state *ps, void __user *arg) | |||
835 | return status; | 893 | return status; |
836 | } | 894 | } |
837 | 895 | ||
838 | |||
839 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | 896 | static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, |
840 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, | 897 | struct usbdevfs_iso_packet_desc __user *iso_frame_desc, |
841 | void __user *arg) | 898 | void __user *arg) |
@@ -896,6 +953,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
896 | kfree(dr); | 953 | kfree(dr); |
897 | return -EFAULT; | 954 | return -EFAULT; |
898 | } | 955 | } |
956 | snoop(&ps->dev->dev, "control urb\n"); | ||
899 | break; | 957 | break; |
900 | 958 | ||
901 | case USBDEVFS_URB_TYPE_BULK: | 959 | case USBDEVFS_URB_TYPE_BULK: |
@@ -910,6 +968,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
910 | return -EINVAL; | 968 | return -EINVAL; |
911 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 969 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) |
912 | return -EFAULT; | 970 | return -EFAULT; |
971 | snoop(&ps->dev->dev, "bulk urb\n"); | ||
913 | break; | 972 | break; |
914 | 973 | ||
915 | case USBDEVFS_URB_TYPE_ISO: | 974 | case USBDEVFS_URB_TYPE_ISO: |
@@ -939,6 +998,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
939 | return -EINVAL; | 998 | return -EINVAL; |
940 | } | 999 | } |
941 | uurb->buffer_length = totlen; | 1000 | uurb->buffer_length = totlen; |
1001 | snoop(&ps->dev->dev, "iso urb\n"); | ||
942 | break; | 1002 | break; |
943 | 1003 | ||
944 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1004 | case USBDEVFS_URB_TYPE_INTERRUPT: |
@@ -954,6 +1014,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
954 | return -EINVAL; | 1014 | return -EINVAL; |
955 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 1015 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) |
956 | return -EFAULT; | 1016 | return -EFAULT; |
1017 | snoop(&ps->dev->dev, "interrupt urb\n"); | ||
957 | break; | 1018 | break; |
958 | 1019 | ||
959 | default: | 1020 | default: |
@@ -1003,6 +1064,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1003 | return -EFAULT; | 1064 | return -EFAULT; |
1004 | } | 1065 | } |
1005 | } | 1066 | } |
1067 | snoop(&as->urb->dev->dev, "submit urb\n"); | ||
1068 | snoop_urb(as->urb, as->userurb); | ||
1006 | async_newpending(as); | 1069 | async_newpending(as); |
1007 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1070 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { |
1008 | dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret); | 1071 | dev_printk(KERN_DEBUG, &ps->dev->dev, "usbfs: usb_submit_urb returned %d\n", ret); |
@@ -1238,23 +1301,20 @@ static int proc_releaseinterface(struct dev_state *ps, void __user *arg) | |||
1238 | return 0; | 1301 | return 0; |
1239 | } | 1302 | } |
1240 | 1303 | ||
1241 | static int proc_ioctl (struct dev_state *ps, void __user *arg) | 1304 | static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) |
1242 | { | 1305 | { |
1243 | struct usbdevfs_ioctl ctrl; | ||
1244 | int size; | 1306 | int size; |
1245 | void *buf = NULL; | 1307 | void *buf = NULL; |
1246 | int retval = 0; | 1308 | int retval = 0; |
1247 | struct usb_interface *intf = NULL; | 1309 | struct usb_interface *intf = NULL; |
1248 | struct usb_driver *driver = NULL; | 1310 | struct usb_driver *driver = NULL; |
1249 | 1311 | ||
1250 | /* get input parameters and alloc buffer */ | 1312 | /* alloc buffer */ |
1251 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) | 1313 | if ((size = _IOC_SIZE (ctl->ioctl_code)) > 0) { |
1252 | return -EFAULT; | ||
1253 | if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) { | ||
1254 | if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) | 1314 | if ((buf = kmalloc (size, GFP_KERNEL)) == NULL) |
1255 | return -ENOMEM; | 1315 | return -ENOMEM; |
1256 | if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) { | 1316 | if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { |
1257 | if (copy_from_user (buf, ctrl.data, size)) { | 1317 | if (copy_from_user (buf, ctl->data, size)) { |
1258 | kfree(buf); | 1318 | kfree(buf); |
1259 | return -EFAULT; | 1319 | return -EFAULT; |
1260 | } | 1320 | } |
@@ -1270,9 +1330,9 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) | |||
1270 | 1330 | ||
1271 | if (ps->dev->state != USB_STATE_CONFIGURED) | 1331 | if (ps->dev->state != USB_STATE_CONFIGURED) |
1272 | retval = -EHOSTUNREACH; | 1332 | retval = -EHOSTUNREACH; |
1273 | else if (!(intf = usb_ifnum_to_if (ps->dev, ctrl.ifno))) | 1333 | else if (!(intf = usb_ifnum_to_if (ps->dev, ctl->ifno))) |
1274 | retval = -EINVAL; | 1334 | retval = -EINVAL; |
1275 | else switch (ctrl.ioctl_code) { | 1335 | else switch (ctl->ioctl_code) { |
1276 | 1336 | ||
1277 | /* disconnect kernel driver from interface */ | 1337 | /* disconnect kernel driver from interface */ |
1278 | case USBDEVFS_DISCONNECT: | 1338 | case USBDEVFS_DISCONNECT: |
@@ -1304,7 +1364,7 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) | |||
1304 | if (driver == NULL || driver->ioctl == NULL) { | 1364 | if (driver == NULL || driver->ioctl == NULL) { |
1305 | retval = -ENOTTY; | 1365 | retval = -ENOTTY; |
1306 | } else { | 1366 | } else { |
1307 | retval = driver->ioctl (intf, ctrl.ioctl_code, buf); | 1367 | retval = driver->ioctl (intf, ctl->ioctl_code, buf); |
1308 | if (retval == -ENOIOCTLCMD) | 1368 | if (retval == -ENOIOCTLCMD) |
1309 | retval = -ENOTTY; | 1369 | retval = -ENOTTY; |
1310 | } | 1370 | } |
@@ -1313,15 +1373,42 @@ static int proc_ioctl (struct dev_state *ps, void __user *arg) | |||
1313 | 1373 | ||
1314 | /* cleanup and return */ | 1374 | /* cleanup and return */ |
1315 | if (retval >= 0 | 1375 | if (retval >= 0 |
1316 | && (_IOC_DIR (ctrl.ioctl_code) & _IOC_READ) != 0 | 1376 | && (_IOC_DIR (ctl->ioctl_code) & _IOC_READ) != 0 |
1317 | && size > 0 | 1377 | && size > 0 |
1318 | && copy_to_user (ctrl.data, buf, size) != 0) | 1378 | && copy_to_user (ctl->data, buf, size) != 0) |
1319 | retval = -EFAULT; | 1379 | retval = -EFAULT; |
1320 | 1380 | ||
1321 | kfree(buf); | 1381 | kfree(buf); |
1322 | return retval; | 1382 | return retval; |
1323 | } | 1383 | } |
1324 | 1384 | ||
1385 | static int proc_ioctl_default(struct dev_state *ps, void __user *arg) | ||
1386 | { | ||
1387 | struct usbdevfs_ioctl ctrl; | ||
1388 | |||
1389 | if (copy_from_user(&ctrl, arg, sizeof (ctrl))) | ||
1390 | return -EFAULT; | ||
1391 | return proc_ioctl(ps, &ctrl); | ||
1392 | } | ||
1393 | |||
1394 | #ifdef CONFIG_COMPAT | ||
1395 | static int proc_ioctl_compat(struct dev_state *ps, void __user *arg) | ||
1396 | { | ||
1397 | struct usbdevfs_ioctl32 __user *uioc; | ||
1398 | struct usbdevfs_ioctl ctrl; | ||
1399 | u32 udata; | ||
1400 | |||
1401 | uioc = compat_ptr(arg); | ||
1402 | if (get_user(ctrl.ifno, &uioc->ifno) || | ||
1403 | get_user(ctrl.ioctl_code, &uioc->ioctl_code) || | ||
1404 | __get_user(udata, &uioc->data)) | ||
1405 | return -EFAULT; | ||
1406 | ctrl.data = compat_ptr(udata); | ||
1407 | |||
1408 | return proc_ioctl(ps, &ctrl); | ||
1409 | } | ||
1410 | #endif | ||
1411 | |||
1325 | /* | 1412 | /* |
1326 | * NOTE: All requests here that have interface numbers as parameters | 1413 | * NOTE: All requests here that have interface numbers as parameters |
1327 | * are assuming that somehow the configuration has been prevented from | 1414 | * are assuming that somehow the configuration has been prevented from |
@@ -1422,6 +1509,10 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
1422 | ret = proc_reapurbnonblock_compat(ps, p); | 1509 | ret = proc_reapurbnonblock_compat(ps, p); |
1423 | break; | 1510 | break; |
1424 | 1511 | ||
1512 | case USBDEVFS_IOCTL32: | ||
1513 | snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); | ||
1514 | ret = proc_ioctl_compat(ps, p); | ||
1515 | break; | ||
1425 | #endif | 1516 | #endif |
1426 | 1517 | ||
1427 | case USBDEVFS_DISCARDURB: | 1518 | case USBDEVFS_DISCARDURB: |
@@ -1456,7 +1547,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
1456 | 1547 | ||
1457 | case USBDEVFS_IOCTL: | 1548 | case USBDEVFS_IOCTL: |
1458 | snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); | 1549 | snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__); |
1459 | ret = proc_ioctl(ps, p); | 1550 | ret = proc_ioctl_default(ps, p); |
1460 | break; | 1551 | break; |
1461 | } | 1552 | } |
1462 | usb_unlock_device(dev); | 1553 | usb_unlock_device(dev); |
@@ -1488,24 +1579,7 @@ struct file_operations usbfs_device_file_operations = { | |||
1488 | .release = usbdev_release, | 1579 | .release = usbdev_release, |
1489 | }; | 1580 | }; |
1490 | 1581 | ||
1491 | struct usb_device *usbdev_lookup_minor(int minor) | 1582 | static void usbdev_add(struct usb_device *dev) |
1492 | { | ||
1493 | struct class_device *class_dev; | ||
1494 | struct usb_device *dev = NULL; | ||
1495 | |||
1496 | down(&usb_device_class->sem); | ||
1497 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | ||
1498 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | ||
1499 | dev = class_dev->class_data; | ||
1500 | break; | ||
1501 | } | ||
1502 | } | ||
1503 | up(&usb_device_class->sem); | ||
1504 | |||
1505 | return dev; | ||
1506 | }; | ||
1507 | |||
1508 | void usbdev_add(struct usb_device *dev) | ||
1509 | { | 1583 | { |
1510 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1584 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1511 | 1585 | ||
@@ -1516,11 +1590,29 @@ void usbdev_add(struct usb_device *dev) | |||
1516 | dev->class_dev->class_data = dev; | 1590 | dev->class_dev->class_data = dev; |
1517 | } | 1591 | } |
1518 | 1592 | ||
1519 | void usbdev_remove(struct usb_device *dev) | 1593 | static void usbdev_remove(struct usb_device *dev) |
1520 | { | 1594 | { |
1521 | class_device_unregister(dev->class_dev); | 1595 | class_device_unregister(dev->class_dev); |
1522 | } | 1596 | } |
1523 | 1597 | ||
1598 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | ||
1599 | void *dev) | ||
1600 | { | ||
1601 | switch (action) { | ||
1602 | case USB_DEVICE_ADD: | ||
1603 | usbdev_add(dev); | ||
1604 | break; | ||
1605 | case USB_DEVICE_REMOVE: | ||
1606 | usbdev_remove(dev); | ||
1607 | break; | ||
1608 | } | ||
1609 | return NOTIFY_OK; | ||
1610 | } | ||
1611 | |||
1612 | static struct notifier_block usbdev_nb = { | ||
1613 | .notifier_call = usbdev_notify, | ||
1614 | }; | ||
1615 | |||
1524 | static struct cdev usb_device_cdev = { | 1616 | static struct cdev usb_device_cdev = { |
1525 | .kobj = {.name = "usb_device", }, | 1617 | .kobj = {.name = "usb_device", }, |
1526 | .owner = THIS_MODULE, | 1618 | .owner = THIS_MODULE, |
@@ -1540,24 +1632,32 @@ int __init usbdev_init(void) | |||
1540 | retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); | 1632 | retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); |
1541 | if (retval) { | 1633 | if (retval) { |
1542 | err("unable to get usb_device major %d", USB_DEVICE_MAJOR); | 1634 | err("unable to get usb_device major %d", USB_DEVICE_MAJOR); |
1543 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | 1635 | goto error_cdev; |
1544 | goto out; | ||
1545 | } | 1636 | } |
1546 | usb_device_class = class_create(THIS_MODULE, "usb_device"); | 1637 | usb_device_class = class_create(THIS_MODULE, "usb_device"); |
1547 | if (IS_ERR(usb_device_class)) { | 1638 | if (IS_ERR(usb_device_class)) { |
1548 | err("unable to register usb_device class"); | 1639 | err("unable to register usb_device class"); |
1549 | retval = PTR_ERR(usb_device_class); | 1640 | retval = PTR_ERR(usb_device_class); |
1550 | usb_device_class = NULL; | 1641 | goto error_class; |
1551 | cdev_del(&usb_device_cdev); | ||
1552 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
1553 | } | 1642 | } |
1554 | 1643 | ||
1644 | usb_register_notify(&usbdev_nb); | ||
1645 | |||
1555 | out: | 1646 | out: |
1556 | return retval; | 1647 | return retval; |
1648 | |||
1649 | error_class: | ||
1650 | usb_device_class = NULL; | ||
1651 | cdev_del(&usb_device_cdev); | ||
1652 | |||
1653 | error_cdev: | ||
1654 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | ||
1655 | goto out; | ||
1557 | } | 1656 | } |
1558 | 1657 | ||
1559 | void usbdev_cleanup(void) | 1658 | void usbdev_cleanup(void) |
1560 | { | 1659 | { |
1660 | usb_unregister_notify(&usbdev_nb); | ||
1561 | class_destroy(usb_device_class); | 1661 | class_destroy(usb_device_class); |
1562 | cdev_del(&usb_device_cdev); | 1662 | cdev_del(&usb_device_cdev); |
1563 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); | 1663 | unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 78cb4be9529f..e695308095ae 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | #include <linux/config.h> | 18 | #include <linux/config.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/devfs_fs_kernel.h> | ||
21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
22 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
23 | 22 | ||
@@ -88,8 +87,6 @@ int usb_major_init(void) | |||
88 | goto out; | 87 | goto out; |
89 | } | 88 | } |
90 | 89 | ||
91 | devfs_mk_dir("usb"); | ||
92 | |||
93 | out: | 90 | out: |
94 | return error; | 91 | return error; |
95 | } | 92 | } |
@@ -97,7 +94,6 @@ out: | |||
97 | void usb_major_cleanup(void) | 94 | void usb_major_cleanup(void) |
98 | { | 95 | { |
99 | class_destroy(usb_class); | 96 | class_destroy(usb_class); |
100 | devfs_remove("usb"); | ||
101 | unregister_chrdev(USB_MAJOR, "usb"); | 97 | unregister_chrdev(USB_MAJOR, "usb"); |
102 | } | 98 | } |
103 | 99 | ||
@@ -112,8 +108,7 @@ void usb_major_cleanup(void) | |||
112 | * enabled, the minor number will be based on the next available free minor, | 108 | * enabled, the minor number will be based on the next available free minor, |
113 | * starting at the class_driver->minor_base. | 109 | * starting at the class_driver->minor_base. |
114 | * | 110 | * |
115 | * This function also creates the devfs file for the usb device, if devfs | 111 | * This function also creates a usb class device in the sysfs tree. |
116 | * is enabled, and creates a usb class device in the sysfs tree. | ||
117 | * | 112 | * |
118 | * usb_deregister_dev() must be called when the driver is done with | 113 | * usb_deregister_dev() must be called when the driver is done with |
119 | * the minor numbers given out by this function. | 114 | * the minor numbers given out by this function. |
@@ -162,11 +157,8 @@ int usb_register_dev(struct usb_interface *intf, | |||
162 | 157 | ||
163 | intf->minor = minor; | 158 | intf->minor = minor; |
164 | 159 | ||
165 | /* handle the devfs registration */ | ||
166 | snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); | ||
167 | devfs_mk_cdev(MKDEV(USB_MAJOR, minor), class_driver->mode, name); | ||
168 | |||
169 | /* create a usb class device for this usb interface */ | 160 | /* create a usb class device for this usb interface */ |
161 | snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base); | ||
170 | temp = strrchr(name, '/'); | 162 | temp = strrchr(name, '/'); |
171 | if (temp && (temp[1] != 0x00)) | 163 | if (temp && (temp[1] != 0x00)) |
172 | ++temp; | 164 | ++temp; |
@@ -179,7 +171,6 @@ int usb_register_dev(struct usb_interface *intf, | |||
179 | spin_lock (&minor_lock); | 171 | spin_lock (&minor_lock); |
180 | usb_minors[intf->minor] = NULL; | 172 | usb_minors[intf->minor] = NULL; |
181 | spin_unlock (&minor_lock); | 173 | spin_unlock (&minor_lock); |
182 | devfs_remove (name); | ||
183 | retval = PTR_ERR(intf->class_dev); | 174 | retval = PTR_ERR(intf->class_dev); |
184 | } | 175 | } |
185 | exit: | 176 | exit: |
@@ -197,9 +188,8 @@ EXPORT_SYMBOL(usb_register_dev); | |||
197 | * call to usb_register_dev() (usually when the device is disconnected | 188 | * call to usb_register_dev() (usually when the device is disconnected |
198 | * from the system.) | 189 | * from the system.) |
199 | * | 190 | * |
200 | * This function also cleans up the devfs file for the usb device, if devfs | 191 | * This function also removes the usb class device from the sysfs tree. |
201 | * is enabled, and removes the usb class device from the sysfs tree. | 192 | * |
202 | * | ||
203 | * This should be called by all drivers that use the USB major number. | 193 | * This should be called by all drivers that use the USB major number. |
204 | */ | 194 | */ |
205 | void usb_deregister_dev(struct usb_interface *intf, | 195 | void usb_deregister_dev(struct usb_interface *intf, |
@@ -222,7 +212,6 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
222 | spin_unlock (&minor_lock); | 212 | spin_unlock (&minor_lock); |
223 | 213 | ||
224 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 214 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
225 | devfs_remove (name); | ||
226 | class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); | 215 | class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); |
227 | intf->class_dev = NULL; | 216 | intf->class_dev = NULL; |
228 | intf->minor = -1; | 217 | intf->minor = -1; |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 6385d1a99b60..84d9e69329bb 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
33 | |||
34 | #include "usb.h" | ||
33 | #include "hcd.h" | 35 | #include "hcd.h" |
34 | 36 | ||
35 | 37 | ||
@@ -197,6 +199,26 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
197 | 199 | ||
198 | hcd = pci_get_drvdata(dev); | 200 | hcd = pci_get_drvdata(dev); |
199 | 201 | ||
202 | /* Root hub suspend should have stopped all downstream traffic, | ||
203 | * and all bus master traffic. And done so for both the interface | ||
204 | * and the stub usb_device (which we check here). But maybe it | ||
205 | * didn't; writing sysfs power/state files ignores such rules... | ||
206 | * | ||
207 | * We must ignore the FREEZE vs SUSPEND distinction here, because | ||
208 | * otherwise the swsusp will save (and restore) garbage state. | ||
209 | */ | ||
210 | if (hcd->self.root_hub->dev.power.power_state.event == PM_EVENT_ON) | ||
211 | return -EBUSY; | ||
212 | |||
213 | if (hcd->driver->suspend) { | ||
214 | retval = hcd->driver->suspend(hcd, message); | ||
215 | if (retval) { | ||
216 | dev_dbg (&dev->dev, "PCI pre-suspend fail, %d\n", | ||
217 | retval); | ||
218 | goto done; | ||
219 | } | ||
220 | } | ||
221 | |||
200 | /* FIXME until the generic PM interfaces change a lot more, this | 222 | /* FIXME until the generic PM interfaces change a lot more, this |
201 | * can't use PCI D1 and D2 states. For example, the confusion | 223 | * can't use PCI D1 and D2 states. For example, the confusion |
202 | * between messages and states will need to vanish, and messages | 224 | * between messages and states will need to vanish, and messages |
@@ -215,31 +237,13 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
215 | */ | 237 | */ |
216 | has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 238 | has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
217 | 239 | ||
218 | switch (hcd->state) { | 240 | /* Downstream ports from this root hub should already be quiesced, so |
219 | 241 | * there will be no DMA activity. Now we can shut down the upstream | |
220 | /* entry if root hub wasn't yet suspended ... from sysfs, | 242 | * link (except maybe for PME# resume signaling) and enter some PCI |
221 | * without autosuspend, or if USB_SUSPEND isn't configured. | 243 | * low power state, if the hardware allows. |
222 | */ | 244 | */ |
223 | case HC_STATE_RUNNING: | 245 | if (hcd->state == HC_STATE_SUSPENDED) { |
224 | hcd->state = HC_STATE_QUIESCING; | ||
225 | retval = hcd->driver->suspend (hcd, message); | ||
226 | if (retval) { | ||
227 | dev_dbg (hcd->self.controller, | ||
228 | "suspend fail, retval %d\n", | ||
229 | retval); | ||
230 | break; | ||
231 | } | ||
232 | hcd->state = HC_STATE_SUSPENDED; | ||
233 | /* FALLTHROUGH */ | ||
234 | 246 | ||
235 | /* entry with CONFIG_USB_SUSPEND, or hcds that autosuspend: the | ||
236 | * controller and/or root hub will already have been suspended, | ||
237 | * but it won't be ready for a PCI resume call. | ||
238 | * | ||
239 | * FIXME only CONFIG_USB_SUSPEND guarantees hub_suspend() will | ||
240 | * have been called, otherwise root hub timers still run ... | ||
241 | */ | ||
242 | case HC_STATE_SUSPENDED: | ||
243 | /* no DMA or IRQs except when HC is active */ | 247 | /* no DMA or IRQs except when HC is active */ |
244 | if (dev->current_state == PCI_D0) { | 248 | if (dev->current_state == PCI_D0) { |
245 | pci_save_state (dev); | 249 | pci_save_state (dev); |
@@ -248,7 +252,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
248 | 252 | ||
249 | if (!has_pci_pm) { | 253 | if (!has_pci_pm) { |
250 | dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n"); | 254 | dev_dbg (hcd->self.controller, "--> PCI D0/legacy\n"); |
251 | break; | 255 | goto done; |
252 | } | 256 | } |
253 | 257 | ||
254 | /* NOTE: dev->current_state becomes nonzero only here, and | 258 | /* NOTE: dev->current_state becomes nonzero only here, and |
@@ -259,28 +263,29 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) | |||
259 | retval = pci_set_power_state (dev, PCI_D3hot); | 263 | retval = pci_set_power_state (dev, PCI_D3hot); |
260 | if (retval == 0) { | 264 | if (retval == 0) { |
261 | dev_dbg (hcd->self.controller, "--> PCI D3\n"); | 265 | dev_dbg (hcd->self.controller, "--> PCI D3\n"); |
262 | retval = pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); | 266 | |
263 | if (retval) | 267 | /* Ignore these return values. We rely on pci code to |
264 | break; | 268 | * reject requests the hardware can't implement, rather |
265 | retval = pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); | 269 | * than coding the same thing. |
266 | } else if (retval < 0) { | 270 | */ |
271 | (void) pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); | ||
272 | (void) pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); | ||
273 | } else { | ||
267 | dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", | 274 | dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", |
268 | retval); | 275 | retval); |
269 | (void) usb_hcd_pci_resume (dev); | 276 | (void) usb_hcd_pci_resume (dev); |
270 | break; | ||
271 | } | 277 | } |
272 | break; | 278 | |
273 | default: | 279 | } else { |
274 | dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", | 280 | dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", |
275 | hcd->state); | 281 | hcd->state); |
276 | WARN_ON(1); | 282 | WARN_ON(1); |
277 | retval = -EINVAL; | 283 | retval = -EINVAL; |
278 | break; | ||
279 | } | 284 | } |
280 | 285 | ||
281 | /* update power_state **ONLY** to make sysfs happier */ | 286 | done: |
282 | if (retval == 0) | 287 | if (retval == 0) |
283 | dev->dev.power.power_state = message; | 288 | dev->dev.power.power_state = PMSG_SUSPEND; |
284 | return retval; | 289 | return retval; |
285 | } | 290 | } |
286 | EXPORT_SYMBOL (usb_hcd_pci_suspend); | 291 | EXPORT_SYMBOL (usb_hcd_pci_suspend); |
@@ -336,20 +341,9 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
336 | dev->current_state); | 341 | dev->current_state); |
337 | } | 342 | } |
338 | #endif | 343 | #endif |
339 | retval = pci_enable_wake (dev, dev->current_state, 0); | 344 | /* yes, ignore these results too... */ |
340 | if (retval) { | 345 | (void) pci_enable_wake (dev, dev->current_state, 0); |
341 | dev_err(hcd->self.controller, | 346 | (void) pci_enable_wake (dev, PCI_D3cold, 0); |
342 | "can't enable_wake to %d, %d!\n", | ||
343 | dev->current_state, retval); | ||
344 | return retval; | ||
345 | } | ||
346 | retval = pci_enable_wake (dev, PCI_D3cold, 0); | ||
347 | if (retval) { | ||
348 | dev_err(hcd->self.controller, | ||
349 | "can't enable_wake to %d, %d!\n", | ||
350 | PCI_D3cold, retval); | ||
351 | return retval; | ||
352 | } | ||
353 | } else { | 347 | } else { |
354 | /* Same basic cases: clean (powered/not), dirty */ | 348 | /* Same basic cases: clean (powered/not), dirty */ |
355 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); | 349 | dev_dbg(hcd->self.controller, "PCI legacy resume\n"); |
@@ -371,17 +365,17 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
371 | 365 | ||
372 | dev->dev.power.power_state = PMSG_ON; | 366 | dev->dev.power.power_state = PMSG_ON; |
373 | 367 | ||
374 | hcd->state = HC_STATE_RESUMING; | ||
375 | hcd->saw_irq = 0; | 368 | hcd->saw_irq = 0; |
376 | 369 | ||
377 | retval = hcd->driver->resume (hcd); | 370 | if (hcd->driver->resume) { |
378 | if (!HC_IS_RUNNING (hcd->state)) { | 371 | retval = hcd->driver->resume(hcd); |
379 | dev_dbg (hcd->self.controller, | 372 | if (retval) { |
380 | "resume fail, retval %d\n", retval); | 373 | dev_err (hcd->self.controller, |
381 | usb_hc_died (hcd); | 374 | "PCI post-resume error %d!\n", retval); |
375 | usb_hc_died (hcd); | ||
376 | } | ||
382 | } | 377 | } |
383 | 378 | ||
384 | retval = pci_enable_device(dev); | ||
385 | return retval; | 379 | return retval; |
386 | } | 380 | } |
387 | EXPORT_SYMBOL (usb_hcd_pci_resume); | 381 | EXPORT_SYMBOL (usb_hcd_pci_resume); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 14c47a10da86..6c7ca5b08cd6 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -130,7 +130,7 @@ static const u8 usb2_rh_dev_descriptor [18] = { | |||
130 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ | 130 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ |
131 | 0x00, /* __u8 bDeviceSubClass; */ | 131 | 0x00, /* __u8 bDeviceSubClass; */ |
132 | 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ | 132 | 0x01, /* __u8 bDeviceProtocol; [ usb 2.0 single TT ]*/ |
133 | 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ | 133 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ |
134 | 134 | ||
135 | 0x00, 0x00, /* __le16 idVendor; */ | 135 | 0x00, 0x00, /* __le16 idVendor; */ |
136 | 0x00, 0x00, /* __le16 idProduct; */ | 136 | 0x00, 0x00, /* __le16 idProduct; */ |
@@ -153,7 +153,7 @@ static const u8 usb11_rh_dev_descriptor [18] = { | |||
153 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ | 153 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ |
154 | 0x00, /* __u8 bDeviceSubClass; */ | 154 | 0x00, /* __u8 bDeviceSubClass; */ |
155 | 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ | 155 | 0x00, /* __u8 bDeviceProtocol; [ low/full speeds only ] */ |
156 | 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ | 156 | 0x40, /* __u8 bMaxPacketSize0; 64 Bytes */ |
157 | 157 | ||
158 | 0x00, 0x00, /* __le16 idVendor; */ | 158 | 0x00, 0x00, /* __le16 idVendor; */ |
159 | 0x00, 0x00, /* __le16 idProduct; */ | 159 | 0x00, 0x00, /* __le16 idProduct; */ |
@@ -458,22 +458,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
458 | 458 | ||
459 | default: | 459 | default: |
460 | /* non-generic request */ | 460 | /* non-generic request */ |
461 | if (HC_IS_SUSPENDED (hcd->state)) | 461 | switch (typeReq) { |
462 | status = -EAGAIN; | 462 | case GetHubStatus: |
463 | else { | 463 | case GetPortStatus: |
464 | switch (typeReq) { | 464 | len = 4; |
465 | case GetHubStatus: | 465 | break; |
466 | case GetPortStatus: | 466 | case GetHubDescriptor: |
467 | len = 4; | 467 | len = sizeof (struct usb_hub_descriptor); |
468 | break; | 468 | break; |
469 | case GetHubDescriptor: | ||
470 | len = sizeof (struct usb_hub_descriptor); | ||
471 | break; | ||
472 | } | ||
473 | status = hcd->driver->hub_control (hcd, | ||
474 | typeReq, wValue, wIndex, | ||
475 | tbuf, wLength); | ||
476 | } | 469 | } |
470 | status = hcd->driver->hub_control (hcd, | ||
471 | typeReq, wValue, wIndex, | ||
472 | tbuf, wLength); | ||
477 | break; | 473 | break; |
478 | error: | 474 | error: |
479 | /* "protocol stall" on error */ | 475 | /* "protocol stall" on error */ |
@@ -487,7 +483,7 @@ error: | |||
487 | "CTRL: TypeReq=0x%x val=0x%x " | 483 | "CTRL: TypeReq=0x%x val=0x%x " |
488 | "idx=0x%x len=%d ==> %d\n", | 484 | "idx=0x%x len=%d ==> %d\n", |
489 | typeReq, wValue, wIndex, | 485 | typeReq, wValue, wIndex, |
490 | wLength, urb->status); | 486 | wLength, status); |
491 | } | 487 | } |
492 | } | 488 | } |
493 | if (len) { | 489 | if (len) { |
@@ -748,10 +744,9 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op) | |||
748 | { | 744 | { |
749 | struct usb_bus *bus; | 745 | struct usb_bus *bus; |
750 | 746 | ||
751 | bus = kmalloc (sizeof *bus, GFP_KERNEL); | 747 | bus = kzalloc (sizeof *bus, GFP_KERNEL); |
752 | if (!bus) | 748 | if (!bus) |
753 | return NULL; | 749 | return NULL; |
754 | memset(bus, 0, sizeof(struct usb_bus)); | ||
755 | usb_bus_init (bus); | 750 | usb_bus_init (bus); |
756 | bus->op = op; | 751 | bus->op = op; |
757 | return bus; | 752 | return bus; |
@@ -796,8 +791,7 @@ static int usb_register_bus(struct usb_bus *bus) | |||
796 | list_add (&bus->bus_list, &usb_bus_list); | 791 | list_add (&bus->bus_list, &usb_bus_list); |
797 | up (&usb_bus_list_lock); | 792 | up (&usb_bus_list_lock); |
798 | 793 | ||
799 | usbfs_add_bus (bus); | 794 | usb_notify_add_bus(bus); |
800 | usbmon_notify_bus_add (bus); | ||
801 | 795 | ||
802 | dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); | 796 | dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); |
803 | return 0; | 797 | return 0; |
@@ -824,8 +818,7 @@ static void usb_deregister_bus (struct usb_bus *bus) | |||
824 | list_del (&bus->bus_list); | 818 | list_del (&bus->bus_list); |
825 | up (&usb_bus_list_lock); | 819 | up (&usb_bus_list_lock); |
826 | 820 | ||
827 | usbmon_notify_bus_remove (bus); | 821 | usb_notify_remove_bus(bus); |
828 | usbfs_remove_bus (bus); | ||
829 | 822 | ||
830 | clear_bit (bus->busnum, busmap.busmap); | 823 | clear_bit (bus->busnum, busmap.busmap); |
831 | 824 | ||
@@ -1143,10 +1136,20 @@ static int hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1143 | else switch (hcd->state) { | 1136 | else switch (hcd->state) { |
1144 | case HC_STATE_RUNNING: | 1137 | case HC_STATE_RUNNING: |
1145 | case HC_STATE_RESUMING: | 1138 | case HC_STATE_RESUMING: |
1139 | doit: | ||
1146 | usb_get_dev (urb->dev); | 1140 | usb_get_dev (urb->dev); |
1147 | list_add_tail (&urb->urb_list, &ep->urb_list); | 1141 | list_add_tail (&urb->urb_list, &ep->urb_list); |
1148 | status = 0; | 1142 | status = 0; |
1149 | break; | 1143 | break; |
1144 | case HC_STATE_SUSPENDED: | ||
1145 | /* HC upstream links (register access, wakeup signaling) can work | ||
1146 | * even when the downstream links (and DMA etc) are quiesced; let | ||
1147 | * usbcore talk to the root hub. | ||
1148 | */ | ||
1149 | if (hcd->self.controller->power.power_state.event == PM_EVENT_ON | ||
1150 | && urb->dev->parent == NULL) | ||
1151 | goto doit; | ||
1152 | /* FALL THROUGH */ | ||
1150 | default: | 1153 | default: |
1151 | status = -ESHUTDOWN; | 1154 | status = -ESHUTDOWN; |
1152 | break; | 1155 | break; |
@@ -1294,12 +1297,6 @@ static int hcd_unlink_urb (struct urb *urb, int status) | |||
1294 | goto done; | 1297 | goto done; |
1295 | } | 1298 | } |
1296 | 1299 | ||
1297 | /* running ~= hc unlink handshake works (irq, timer, etc) | ||
1298 | * halted ~= no unlink handshake is needed | ||
1299 | * suspended, resuming == should never happen | ||
1300 | */ | ||
1301 | WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT); | ||
1302 | |||
1303 | /* insist the urb is still queued */ | 1300 | /* insist the urb is still queued */ |
1304 | list_for_each(tmp, &ep->urb_list) { | 1301 | list_for_each(tmp, &ep->urb_list) { |
1305 | if (tmp == &urb->urb_list) | 1302 | if (tmp == &urb->urb_list) |
@@ -1431,28 +1428,92 @@ rescan: | |||
1431 | 1428 | ||
1432 | /*-------------------------------------------------------------------------*/ | 1429 | /*-------------------------------------------------------------------------*/ |
1433 | 1430 | ||
1434 | #ifdef CONFIG_USB_SUSPEND | 1431 | #ifdef CONFIG_PM |
1435 | 1432 | ||
1436 | static int hcd_hub_suspend (struct usb_bus *bus) | 1433 | int hcd_bus_suspend (struct usb_bus *bus) |
1437 | { | 1434 | { |
1438 | struct usb_hcd *hcd; | 1435 | struct usb_hcd *hcd; |
1436 | int status; | ||
1439 | 1437 | ||
1440 | hcd = container_of (bus, struct usb_hcd, self); | 1438 | hcd = container_of (bus, struct usb_hcd, self); |
1441 | if (hcd->driver->hub_suspend) | 1439 | if (!hcd->driver->bus_suspend) |
1442 | return hcd->driver->hub_suspend (hcd); | 1440 | return -ENOENT; |
1443 | return 0; | 1441 | hcd->state = HC_STATE_QUIESCING; |
1442 | status = hcd->driver->bus_suspend (hcd); | ||
1443 | if (status == 0) | ||
1444 | hcd->state = HC_STATE_SUSPENDED; | ||
1445 | else | ||
1446 | dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n", | ||
1447 | "suspend", status); | ||
1448 | return status; | ||
1444 | } | 1449 | } |
1445 | 1450 | ||
1446 | static int hcd_hub_resume (struct usb_bus *bus) | 1451 | int hcd_bus_resume (struct usb_bus *bus) |
1447 | { | 1452 | { |
1448 | struct usb_hcd *hcd; | 1453 | struct usb_hcd *hcd; |
1454 | int status; | ||
1449 | 1455 | ||
1450 | hcd = container_of (bus, struct usb_hcd, self); | 1456 | hcd = container_of (bus, struct usb_hcd, self); |
1451 | if (hcd->driver->hub_resume) | 1457 | if (!hcd->driver->bus_resume) |
1452 | return hcd->driver->hub_resume (hcd); | 1458 | return -ENOENT; |
1453 | return 0; | 1459 | if (hcd->state == HC_STATE_RUNNING) |
1460 | return 0; | ||
1461 | hcd->state = HC_STATE_RESUMING; | ||
1462 | status = hcd->driver->bus_resume (hcd); | ||
1463 | if (status == 0) | ||
1464 | hcd->state = HC_STATE_RUNNING; | ||
1465 | else { | ||
1466 | dev_dbg(&bus->root_hub->dev, "%s fail, err %d\n", | ||
1467 | "resume", status); | ||
1468 | usb_hc_died(hcd); | ||
1469 | } | ||
1470 | return status; | ||
1454 | } | 1471 | } |
1455 | 1472 | ||
1473 | /* | ||
1474 | * usb_hcd_suspend_root_hub - HCD autosuspends downstream ports | ||
1475 | * @hcd: host controller for this root hub | ||
1476 | * | ||
1477 | * This call arranges that usb_hcd_resume_root_hub() is safe to call later; | ||
1478 | * that the HCD's root hub polling is deactivated; and that the root's hub | ||
1479 | * driver is suspended. HCDs may call this to autosuspend when their root | ||
1480 | * hub's downstream ports are all inactive: unpowered, disconnected, | ||
1481 | * disabled, or suspended. | ||
1482 | * | ||
1483 | * The HCD will autoresume on device connect change detection (using SRP | ||
1484 | * or a D+/D- pullup). The HCD also autoresumes on remote wakeup signaling | ||
1485 | * from any ports that are suspended (if that is enabled). In most cases, | ||
1486 | * overcurrent signaling (on powered ports) will also start autoresume. | ||
1487 | * | ||
1488 | * Always called with IRQs blocked. | ||
1489 | */ | ||
1490 | void usb_hcd_suspend_root_hub (struct usb_hcd *hcd) | ||
1491 | { | ||
1492 | struct urb *urb; | ||
1493 | |||
1494 | spin_lock (&hcd_root_hub_lock); | ||
1495 | usb_suspend_root_hub (hcd->self.root_hub); | ||
1496 | |||
1497 | /* force status urb to complete/unlink while suspended */ | ||
1498 | if (hcd->status_urb) { | ||
1499 | urb = hcd->status_urb; | ||
1500 | urb->status = -ECONNRESET; | ||
1501 | urb->hcpriv = NULL; | ||
1502 | urb->actual_length = 0; | ||
1503 | |||
1504 | del_timer (&hcd->rh_timer); | ||
1505 | hcd->poll_pending = 0; | ||
1506 | hcd->status_urb = NULL; | ||
1507 | } else | ||
1508 | urb = NULL; | ||
1509 | spin_unlock (&hcd_root_hub_lock); | ||
1510 | hcd->state = HC_STATE_SUSPENDED; | ||
1511 | |||
1512 | if (urb) | ||
1513 | usb_hcd_giveback_urb (hcd, urb, NULL); | ||
1514 | } | ||
1515 | EXPORT_SYMBOL_GPL(usb_hcd_suspend_root_hub); | ||
1516 | |||
1456 | /** | 1517 | /** |
1457 | * usb_hcd_resume_root_hub - called by HCD to resume its root hub | 1518 | * usb_hcd_resume_root_hub - called by HCD to resume its root hub |
1458 | * @hcd: host controller for this root hub | 1519 | * @hcd: host controller for this root hub |
@@ -1460,7 +1521,7 @@ static int hcd_hub_resume (struct usb_bus *bus) | |||
1460 | * The USB host controller calls this function when its root hub is | 1521 | * The USB host controller calls this function when its root hub is |
1461 | * suspended (with the remote wakeup feature enabled) and a remote | 1522 | * suspended (with the remote wakeup feature enabled) and a remote |
1462 | * wakeup request is received. It queues a request for khubd to | 1523 | * wakeup request is received. It queues a request for khubd to |
1463 | * resume the root hub. | 1524 | * resume the root hub (that is, manage its downstream ports again). |
1464 | */ | 1525 | */ |
1465 | void usb_hcd_resume_root_hub (struct usb_hcd *hcd) | 1526 | void usb_hcd_resume_root_hub (struct usb_hcd *hcd) |
1466 | { | 1527 | { |
@@ -1471,13 +1532,9 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) | |||
1471 | usb_resume_root_hub (hcd->self.root_hub); | 1532 | usb_resume_root_hub (hcd->self.root_hub); |
1472 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); | 1533 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); |
1473 | } | 1534 | } |
1535 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); | ||
1474 | 1536 | ||
1475 | #else | ||
1476 | void usb_hcd_resume_root_hub (struct usb_hcd *hcd) | ||
1477 | { | ||
1478 | } | ||
1479 | #endif | 1537 | #endif |
1480 | EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); | ||
1481 | 1538 | ||
1482 | /*-------------------------------------------------------------------------*/ | 1539 | /*-------------------------------------------------------------------------*/ |
1483 | 1540 | ||
@@ -1530,10 +1587,6 @@ static struct usb_operations usb_hcd_operations = { | |||
1530 | .buffer_alloc = hcd_buffer_alloc, | 1587 | .buffer_alloc = hcd_buffer_alloc, |
1531 | .buffer_free = hcd_buffer_free, | 1588 | .buffer_free = hcd_buffer_free, |
1532 | .disable = hcd_endpoint_disable, | 1589 | .disable = hcd_endpoint_disable, |
1533 | #ifdef CONFIG_USB_SUSPEND | ||
1534 | .hub_suspend = hcd_hub_suspend, | ||
1535 | .hub_resume = hcd_hub_resume, | ||
1536 | #endif | ||
1537 | }; | 1590 | }; |
1538 | 1591 | ||
1539 | /*-------------------------------------------------------------------------*/ | 1592 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 1f1ed6211af8..24a62a2ff86d 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -154,10 +154,6 @@ struct usb_operations { | |||
154 | 154 | ||
155 | void (*disable)(struct usb_device *udev, | 155 | void (*disable)(struct usb_device *udev, |
156 | struct usb_host_endpoint *ep); | 156 | struct usb_host_endpoint *ep); |
157 | |||
158 | /* global suspend/resume of bus */ | ||
159 | int (*hub_suspend)(struct usb_bus *); | ||
160 | int (*hub_resume)(struct usb_bus *); | ||
161 | }; | 157 | }; |
162 | 158 | ||
163 | /* each driver provides one of these, and hardware init support */ | 159 | /* each driver provides one of these, and hardware init support */ |
@@ -182,12 +178,12 @@ struct hc_driver { | |||
182 | int (*start) (struct usb_hcd *hcd); | 178 | int (*start) (struct usb_hcd *hcd); |
183 | 179 | ||
184 | /* NOTE: these suspend/resume calls relate to the HC as | 180 | /* NOTE: these suspend/resume calls relate to the HC as |
185 | * a whole, not just the root hub; they're for bus glue. | 181 | * a whole, not just the root hub; they're for PCI bus glue. |
186 | */ | 182 | */ |
187 | /* called after all devices were suspended */ | 183 | /* called after suspending the hub, before entering D3 etc */ |
188 | int (*suspend) (struct usb_hcd *hcd, pm_message_t message); | 184 | int (*suspend) (struct usb_hcd *hcd, pm_message_t message); |
189 | 185 | ||
190 | /* called before any devices get resumed */ | 186 | /* called after entering D0 (etc), before resuming the hub */ |
191 | int (*resume) (struct usb_hcd *hcd); | 187 | int (*resume) (struct usb_hcd *hcd); |
192 | 188 | ||
193 | /* cleanly make HCD stop writing memory and doing I/O */ | 189 | /* cleanly make HCD stop writing memory and doing I/O */ |
@@ -212,8 +208,8 @@ struct hc_driver { | |||
212 | int (*hub_control) (struct usb_hcd *hcd, | 208 | int (*hub_control) (struct usb_hcd *hcd, |
213 | u16 typeReq, u16 wValue, u16 wIndex, | 209 | u16 typeReq, u16 wValue, u16 wIndex, |
214 | char *buf, u16 wLength); | 210 | char *buf, u16 wLength); |
215 | int (*hub_suspend)(struct usb_hcd *); | 211 | int (*bus_suspend)(struct usb_hcd *); |
216 | int (*hub_resume)(struct usb_hcd *); | 212 | int (*bus_resume)(struct usb_hcd *); |
217 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); | 213 | int (*start_port_reset)(struct usb_hcd *, unsigned port_num); |
218 | void (*hub_irq_enable)(struct usb_hcd *); | 214 | void (*hub_irq_enable)(struct usb_hcd *); |
219 | /* Needed only if port-change IRQs are level-triggered */ | 215 | /* Needed only if port-change IRQs are level-triggered */ |
@@ -355,8 +351,6 @@ extern long usb_calc_bus_time (int speed, int is_input, | |||
355 | 351 | ||
356 | extern struct usb_bus *usb_alloc_bus (struct usb_operations *); | 352 | extern struct usb_bus *usb_alloc_bus (struct usb_operations *); |
357 | 353 | ||
358 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | ||
359 | |||
360 | extern void usb_set_device_state(struct usb_device *udev, | 354 | extern void usb_set_device_state(struct usb_device *udev, |
361 | enum usb_device_state new_state); | 355 | enum usb_device_state new_state); |
362 | 356 | ||
@@ -378,6 +372,33 @@ extern int usb_find_interface_driver (struct usb_device *dev, | |||
378 | 372 | ||
379 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) | 373 | #define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) |
380 | 374 | ||
375 | #ifdef CONFIG_PM | ||
376 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); | ||
377 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | ||
378 | extern int hcd_bus_suspend (struct usb_bus *bus); | ||
379 | extern int hcd_bus_resume (struct usb_bus *bus); | ||
380 | #else | ||
381 | static inline void usb_hcd_suspend_root_hub(struct usb_hcd *hcd) | ||
382 | { | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | static inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) | ||
387 | { | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | static inline int hcd_bus_suspend(struct usb_bus *bus) | ||
392 | { | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static inline int hcd_bus_resume (struct usb_bus *bus) | ||
397 | { | ||
398 | return 0; | ||
399 | } | ||
400 | #endif /* CONFIG_PM */ | ||
401 | |||
381 | /* | 402 | /* |
382 | * USB device fs stuff | 403 | * USB device fs stuff |
383 | */ | 404 | */ |
@@ -388,23 +409,13 @@ extern int usb_find_interface_driver (struct usb_device *dev, | |||
388 | * these are expected to be called from the USB core/hub thread | 409 | * these are expected to be called from the USB core/hub thread |
389 | * with the kernel lock held | 410 | * with the kernel lock held |
390 | */ | 411 | */ |
391 | extern void usbfs_add_bus(struct usb_bus *bus); | ||
392 | extern void usbfs_remove_bus(struct usb_bus *bus); | ||
393 | extern void usbfs_add_device(struct usb_device *dev); | ||
394 | extern void usbfs_remove_device(struct usb_device *dev); | ||
395 | extern void usbfs_update_special (void); | 412 | extern void usbfs_update_special (void); |
396 | |||
397 | extern int usbfs_init(void); | 413 | extern int usbfs_init(void); |
398 | extern void usbfs_cleanup(void); | 414 | extern void usbfs_cleanup(void); |
399 | 415 | ||
400 | #else /* CONFIG_USB_DEVICEFS */ | 416 | #else /* CONFIG_USB_DEVICEFS */ |
401 | 417 | ||
402 | static inline void usbfs_add_bus(struct usb_bus *bus) {} | ||
403 | static inline void usbfs_remove_bus(struct usb_bus *bus) {} | ||
404 | static inline void usbfs_add_device(struct usb_device *dev) {} | ||
405 | static inline void usbfs_remove_device(struct usb_device *dev) {} | ||
406 | static inline void usbfs_update_special (void) {} | 418 | static inline void usbfs_update_special (void) {} |
407 | |||
408 | static inline int usbfs_init(void) { return 0; } | 419 | static inline int usbfs_init(void) { return 0; } |
409 | static inline void usbfs_cleanup(void) { } | 420 | static inline void usbfs_cleanup(void) { } |
410 | 421 | ||
@@ -419,8 +430,6 @@ struct usb_mon_operations { | |||
419 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); | 430 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); |
420 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb); | 431 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb); |
421 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ | 432 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ |
422 | void (*bus_add)(struct usb_bus *bus); | ||
423 | void (*bus_remove)(struct usb_bus *bus); | ||
424 | }; | 433 | }; |
425 | 434 | ||
426 | extern struct usb_mon_operations *mon_ops; | 435 | extern struct usb_mon_operations *mon_ops; |
@@ -443,18 +452,6 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) | |||
443 | if (bus->monitored) | 452 | if (bus->monitored) |
444 | (*mon_ops->urb_complete)(bus, urb); | 453 | (*mon_ops->urb_complete)(bus, urb); |
445 | } | 454 | } |
446 | |||
447 | static inline void usbmon_notify_bus_add(struct usb_bus *bus) | ||
448 | { | ||
449 | if (mon_ops) | ||
450 | (*mon_ops->bus_add)(bus); | ||
451 | } | ||
452 | |||
453 | static inline void usbmon_notify_bus_remove(struct usb_bus *bus) | ||
454 | { | ||
455 | if (mon_ops) | ||
456 | (*mon_ops->bus_remove)(bus); | ||
457 | } | ||
458 | 455 | ||
459 | int usb_mon_register(struct usb_mon_operations *ops); | 456 | int usb_mon_register(struct usb_mon_operations *ops); |
460 | void usb_mon_deregister(void); | 457 | void usb_mon_deregister(void); |
@@ -465,8 +462,6 @@ static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} | |||
465 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, | 462 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, |
466 | int error) {} | 463 | int error) {} |
467 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} | 464 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} |
468 | static inline void usbmon_notify_bus_add(struct usb_bus *bus) {} | ||
469 | static inline void usbmon_notify_bus_remove(struct usb_bus *bus) {} | ||
470 | 465 | ||
471 | #endif /* CONFIG_USB_MON */ | 466 | #endif /* CONFIG_USB_MON */ |
472 | 467 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c3e2024c4347..256d9f698715 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -436,9 +436,10 @@ static void hub_power_on(struct usb_hub *hub) | |||
436 | { | 436 | { |
437 | int port1; | 437 | int port1; |
438 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; | 438 | unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2; |
439 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | ||
439 | 440 | ||
440 | /* if hub supports power switching, enable power on each port */ | 441 | /* if hub supports power switching, enable power on each port */ |
441 | if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) < 2) { | 442 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2) { |
442 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); | 443 | dev_dbg(hub->intfdev, "enabling power on all ports\n"); |
443 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) | 444 | for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) |
444 | set_port_feature(hub->hdev, port1, | 445 | set_port_feature(hub->hdev, port1, |
@@ -449,10 +450,18 @@ static void hub_power_on(struct usb_hub *hub) | |||
449 | msleep(max(pgood_delay, (unsigned) 100)); | 450 | msleep(max(pgood_delay, (unsigned) 100)); |
450 | } | 451 | } |
451 | 452 | ||
452 | static void hub_quiesce(struct usb_hub *hub) | 453 | static inline void __hub_quiesce(struct usb_hub *hub) |
453 | { | 454 | { |
454 | /* stop khubd and related activity */ | 455 | /* (nonblocking) khubd and related activity won't re-trigger */ |
455 | hub->quiescing = 1; | 456 | hub->quiescing = 1; |
457 | hub->activating = 0; | ||
458 | hub->resume_root_hub = 0; | ||
459 | } | ||
460 | |||
461 | static void hub_quiesce(struct usb_hub *hub) | ||
462 | { | ||
463 | /* (blocking) stop khubd and related activity */ | ||
464 | __hub_quiesce(hub); | ||
456 | usb_kill_urb(hub->urb); | 465 | usb_kill_urb(hub->urb); |
457 | if (hub->has_indicators) | 466 | if (hub->has_indicators) |
458 | cancel_delayed_work(&hub->leds); | 467 | cancel_delayed_work(&hub->leds); |
@@ -466,6 +475,7 @@ static void hub_activate(struct usb_hub *hub) | |||
466 | 475 | ||
467 | hub->quiescing = 0; | 476 | hub->quiescing = 0; |
468 | hub->activating = 1; | 477 | hub->activating = 1; |
478 | hub->resume_root_hub = 0; | ||
469 | status = usb_submit_urb(hub->urb, GFP_NOIO); | 479 | status = usb_submit_urb(hub->urb, GFP_NOIO); |
470 | if (status < 0) | 480 | if (status < 0) |
471 | dev_err(hub->intfdev, "activate --> %d\n", status); | 481 | dev_err(hub->intfdev, "activate --> %d\n", status); |
@@ -516,6 +526,7 @@ static int hub_configure(struct usb_hub *hub, | |||
516 | struct usb_device *hdev = hub->hdev; | 526 | struct usb_device *hdev = hub->hdev; |
517 | struct device *hub_dev = hub->intfdev; | 527 | struct device *hub_dev = hub->intfdev; |
518 | u16 hubstatus, hubchange; | 528 | u16 hubstatus, hubchange; |
529 | u16 wHubCharacteristics; | ||
519 | unsigned int pipe; | 530 | unsigned int pipe; |
520 | int maxp, ret; | 531 | int maxp, ret; |
521 | char *message; | 532 | char *message; |
@@ -561,9 +572,9 @@ static int hub_configure(struct usb_hub *hub, | |||
561 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, | 572 | dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, |
562 | (hdev->maxchild == 1) ? "" : "s"); | 573 | (hdev->maxchild == 1) ? "" : "s"); |
563 | 574 | ||
564 | le16_to_cpus(&hub->descriptor->wHubCharacteristics); | 575 | wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); |
565 | 576 | ||
566 | if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND) { | 577 | if (wHubCharacteristics & HUB_CHAR_COMPOUND) { |
567 | int i; | 578 | int i; |
568 | char portstr [USB_MAXCHILDREN + 1]; | 579 | char portstr [USB_MAXCHILDREN + 1]; |
569 | 580 | ||
@@ -576,7 +587,7 @@ static int hub_configure(struct usb_hub *hub, | |||
576 | } else | 587 | } else |
577 | dev_dbg(hub_dev, "standalone hub\n"); | 588 | dev_dbg(hub_dev, "standalone hub\n"); |
578 | 589 | ||
579 | switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) { | 590 | switch (wHubCharacteristics & HUB_CHAR_LPSM) { |
580 | case 0x00: | 591 | case 0x00: |
581 | dev_dbg(hub_dev, "ganged power switching\n"); | 592 | dev_dbg(hub_dev, "ganged power switching\n"); |
582 | break; | 593 | break; |
@@ -589,7 +600,7 @@ static int hub_configure(struct usb_hub *hub, | |||
589 | break; | 600 | break; |
590 | } | 601 | } |
591 | 602 | ||
592 | switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { | 603 | switch (wHubCharacteristics & HUB_CHAR_OCPM) { |
593 | case 0x00: | 604 | case 0x00: |
594 | dev_dbg(hub_dev, "global over-current protection\n"); | 605 | dev_dbg(hub_dev, "global over-current protection\n"); |
595 | break; | 606 | break; |
@@ -629,7 +640,7 @@ static int hub_configure(struct usb_hub *hub, | |||
629 | } | 640 | } |
630 | 641 | ||
631 | /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ | 642 | /* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ |
632 | switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) { | 643 | switch (wHubCharacteristics & HUB_CHAR_TTTT) { |
633 | case HUB_TTTT_8_BITS: | 644 | case HUB_TTTT_8_BITS: |
634 | if (hdev->descriptor.bDeviceProtocol != 0) { | 645 | if (hdev->descriptor.bDeviceProtocol != 0) { |
635 | hub->tt.think_time = 666; | 646 | hub->tt.think_time = 666; |
@@ -659,7 +670,7 @@ static int hub_configure(struct usb_hub *hub, | |||
659 | } | 670 | } |
660 | 671 | ||
661 | /* probe() zeroes hub->indicator[] */ | 672 | /* probe() zeroes hub->indicator[] */ |
662 | if (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) { | 673 | if (wHubCharacteristics & HUB_CHAR_PORTIND) { |
663 | hub->has_indicators = 1; | 674 | hub->has_indicators = 1; |
664 | dev_dbg(hub_dev, "Port indicators are supported\n"); | 675 | dev_dbg(hub_dev, "Port indicators are supported\n"); |
665 | } | 676 | } |
@@ -704,7 +715,7 @@ static int hub_configure(struct usb_hub *hub, | |||
704 | (hubstatus & HUB_STATUS_LOCAL_POWER) | 715 | (hubstatus & HUB_STATUS_LOCAL_POWER) |
705 | ? "lost (inactive)" : "good"); | 716 | ? "lost (inactive)" : "good"); |
706 | 717 | ||
707 | if ((hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) == 0) | 718 | if ((wHubCharacteristics & HUB_CHAR_OCPM) == 0) |
708 | dev_dbg(hub_dev, "%sover-current condition exists\n", | 719 | dev_dbg(hub_dev, "%sover-current condition exists\n", |
709 | (hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); | 720 | (hubstatus & HUB_STATUS_OVERCURRENT) ? "" : "no "); |
710 | 721 | ||
@@ -854,14 +865,12 @@ descriptor_error: | |||
854 | /* We found a hub */ | 865 | /* We found a hub */ |
855 | dev_info (&intf->dev, "USB hub found\n"); | 866 | dev_info (&intf->dev, "USB hub found\n"); |
856 | 867 | ||
857 | hub = kmalloc(sizeof(*hub), GFP_KERNEL); | 868 | hub = kzalloc(sizeof(*hub), GFP_KERNEL); |
858 | if (!hub) { | 869 | if (!hub) { |
859 | dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); | 870 | dev_dbg (&intf->dev, "couldn't kmalloc hub struct\n"); |
860 | return -ENOMEM; | 871 | return -ENOMEM; |
861 | } | 872 | } |
862 | 873 | ||
863 | memset(hub, 0, sizeof(*hub)); | ||
864 | |||
865 | INIT_LIST_HEAD(&hub->event_list); | 874 | INIT_LIST_HEAD(&hub->event_list); |
866 | hub->intfdev = &intf->dev; | 875 | hub->intfdev = &intf->dev; |
867 | hub->hdev = hdev; | 876 | hub->hdev = hdev; |
@@ -1117,14 +1126,14 @@ void usb_disconnect(struct usb_device **pdev) | |||
1117 | */ | 1126 | */ |
1118 | usb_disable_device(udev, 0); | 1127 | usb_disable_device(udev, 0); |
1119 | 1128 | ||
1129 | usb_notify_remove_device(udev); | ||
1130 | |||
1120 | /* Free the device number, remove the /proc/bus/usb entry and | 1131 | /* Free the device number, remove the /proc/bus/usb entry and |
1121 | * the sysfs attributes, and delete the parent's children[] | 1132 | * the sysfs attributes, and delete the parent's children[] |
1122 | * (or root_hub) pointer. | 1133 | * (or root_hub) pointer. |
1123 | */ | 1134 | */ |
1124 | dev_dbg (&udev->dev, "unregistering device\n"); | 1135 | dev_dbg (&udev->dev, "unregistering device\n"); |
1125 | release_address(udev); | 1136 | release_address(udev); |
1126 | usbfs_remove_device(udev); | ||
1127 | usbdev_remove(udev); | ||
1128 | usb_remove_sysfs_dev_files(udev); | 1137 | usb_remove_sysfs_dev_files(udev); |
1129 | 1138 | ||
1130 | /* Avoid races with recursively_mark_NOTATTACHED() */ | 1139 | /* Avoid races with recursively_mark_NOTATTACHED() */ |
@@ -1195,21 +1204,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1195 | {} | 1204 | {} |
1196 | #endif | 1205 | #endif |
1197 | 1206 | ||
1198 | static void get_string(struct usb_device *udev, char **string, int index) | ||
1199 | { | ||
1200 | char *buf; | ||
1201 | |||
1202 | if (!index) | ||
1203 | return; | ||
1204 | buf = kmalloc(256, GFP_KERNEL); | ||
1205 | if (!buf) | ||
1206 | return; | ||
1207 | if (usb_string(udev, index, buf, 256) > 0) | ||
1208 | *string = buf; | ||
1209 | else | ||
1210 | kfree(buf); | ||
1211 | } | ||
1212 | |||
1213 | 1207 | ||
1214 | #ifdef CONFIG_USB_OTG | 1208 | #ifdef CONFIG_USB_OTG |
1215 | #include "otg_whitelist.h" | 1209 | #include "otg_whitelist.h" |
@@ -1248,9 +1242,10 @@ int usb_new_device(struct usb_device *udev) | |||
1248 | } | 1242 | } |
1249 | 1243 | ||
1250 | /* read the standard strings and cache them if present */ | 1244 | /* read the standard strings and cache them if present */ |
1251 | get_string(udev, &udev->product, udev->descriptor.iProduct); | 1245 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); |
1252 | get_string(udev, &udev->manufacturer, udev->descriptor.iManufacturer); | 1246 | udev->manufacturer = usb_cache_string(udev, |
1253 | get_string(udev, &udev->serial, udev->descriptor.iSerialNumber); | 1247 | udev->descriptor.iManufacturer); |
1248 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
1254 | 1249 | ||
1255 | /* Tell the world! */ | 1250 | /* Tell the world! */ |
1256 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | 1251 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " |
@@ -1322,11 +1317,9 @@ int usb_new_device(struct usb_device *udev) | |||
1322 | * (Includes HNP test device.) | 1317 | * (Includes HNP test device.) |
1323 | */ | 1318 | */ |
1324 | if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { | 1319 | if (udev->bus->b_hnp_enable || udev->bus->is_b_host) { |
1325 | static int __usb_suspend_device (struct usb_device *, | 1320 | static int __usb_suspend_device(struct usb_device *, |
1326 | int port1, pm_message_t state); | 1321 | int port1); |
1327 | err = __usb_suspend_device(udev, | 1322 | err = __usb_suspend_device(udev, udev->bus->otg_port); |
1328 | udev->bus->otg_port, | ||
1329 | PMSG_SUSPEND); | ||
1330 | if (err < 0) | 1323 | if (err < 0) |
1331 | dev_dbg(&udev->dev, "HNP fail, %d\n", err); | 1324 | dev_dbg(&udev->dev, "HNP fail, %d\n", err); |
1332 | } | 1325 | } |
@@ -1362,10 +1355,8 @@ int usb_new_device(struct usb_device *udev) | |||
1362 | } | 1355 | } |
1363 | 1356 | ||
1364 | /* USB device state == configured ... usable */ | 1357 | /* USB device state == configured ... usable */ |
1358 | usb_notify_add_device(udev); | ||
1365 | 1359 | ||
1366 | /* add a /proc/bus/usb entry */ | ||
1367 | usbdev_add(udev); | ||
1368 | usbfs_add_device(udev); | ||
1369 | return 0; | 1360 | return 0; |
1370 | 1361 | ||
1371 | fail: | 1362 | fail: |
@@ -1516,7 +1507,7 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) | |||
1516 | /* FIXME let caller ask to power down the port: | 1507 | /* FIXME let caller ask to power down the port: |
1517 | * - some devices won't enumerate without a VBUS power cycle | 1508 | * - some devices won't enumerate without a VBUS power cycle |
1518 | * - SRP saves power that way | 1509 | * - SRP saves power that way |
1519 | * - usb_suspend_device(dev, PMSG_SUSPEND) | 1510 | * - ... new call, TBD ... |
1520 | * That's easy if this hub can switch power per-port, and | 1511 | * That's easy if this hub can switch power per-port, and |
1521 | * khubd reactivates the port later (timer, SRP, etc). | 1512 | * khubd reactivates the port later (timer, SRP, etc). |
1522 | * Powerdown must be optional, because of reset/DFU. | 1513 | * Powerdown must be optional, because of reset/DFU. |
@@ -1598,11 +1589,14 @@ static int hub_port_suspend(struct usb_hub *hub, int port1, | |||
1598 | * Other than re-initializing the hub (plug/unplug, except for root hubs), | 1589 | * Other than re-initializing the hub (plug/unplug, except for root hubs), |
1599 | * Linux (2.6) currently has NO mechanisms to initiate that: no khubd | 1590 | * Linux (2.6) currently has NO mechanisms to initiate that: no khubd |
1600 | * timer, no SRP, no requests through sysfs. | 1591 | * timer, no SRP, no requests through sysfs. |
1592 | * | ||
1593 | * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when | ||
1594 | * the root hub for their bus goes into global suspend ... so we don't | ||
1595 | * (falsely) update the device power state to say it suspended. | ||
1601 | */ | 1596 | */ |
1602 | static int __usb_suspend_device (struct usb_device *udev, int port1, | 1597 | static int __usb_suspend_device (struct usb_device *udev, int port1) |
1603 | pm_message_t state) | ||
1604 | { | 1598 | { |
1605 | int status; | 1599 | int status = 0; |
1606 | 1600 | ||
1607 | /* caller owns the udev device lock */ | 1601 | /* caller owns the udev device lock */ |
1608 | if (port1 < 0) | 1602 | if (port1 < 0) |
@@ -1613,95 +1607,39 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, | |||
1613 | return 0; | 1607 | return 0; |
1614 | } | 1608 | } |
1615 | 1609 | ||
1616 | /* suspend interface drivers; if this is a hub, it | 1610 | /* all interfaces must already be suspended */ |
1617 | * suspends the child devices | ||
1618 | */ | ||
1619 | if (udev->actconfig) { | 1611 | if (udev->actconfig) { |
1620 | int i; | 1612 | int i; |
1621 | 1613 | ||
1622 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 1614 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1623 | struct usb_interface *intf; | 1615 | struct usb_interface *intf; |
1624 | struct usb_driver *driver; | ||
1625 | 1616 | ||
1626 | intf = udev->actconfig->interface[i]; | 1617 | intf = udev->actconfig->interface[i]; |
1627 | if (state.event <= intf->dev.power.power_state.event) | 1618 | if (is_active(intf)) { |
1628 | continue; | 1619 | dev_dbg(&intf->dev, "nyet suspended\n"); |
1629 | if (!intf->dev.driver) | 1620 | return -EBUSY; |
1630 | continue; | ||
1631 | driver = to_usb_driver(intf->dev.driver); | ||
1632 | |||
1633 | if (driver->suspend) { | ||
1634 | status = driver->suspend(intf, state); | ||
1635 | if (intf->dev.power.power_state.event != state.event | ||
1636 | || status) | ||
1637 | dev_err(&intf->dev, | ||
1638 | "suspend %d fail, code %d\n", | ||
1639 | state.event, status); | ||
1640 | } | ||
1641 | |||
1642 | /* only drivers with suspend() can ever resume(); | ||
1643 | * and after power loss, even they won't. | ||
1644 | * bus_rescan_devices() can rebind drivers later. | ||
1645 | * | ||
1646 | * FIXME the PM core self-deadlocks when unbinding | ||
1647 | * drivers during suspend/resume ... everything grabs | ||
1648 | * dpm_sem (not a spinlock, ugh). we want to unbind, | ||
1649 | * since we know every driver's probe/disconnect works | ||
1650 | * even for drivers that can't suspend. | ||
1651 | */ | ||
1652 | if (!driver->suspend || state.event > PM_EVENT_FREEZE) { | ||
1653 | #if 1 | ||
1654 | dev_warn(&intf->dev, "resume is unsafe!\n"); | ||
1655 | #else | ||
1656 | down_write(&usb_bus_type.rwsem); | ||
1657 | device_release_driver(&intf->dev); | ||
1658 | up_write(&usb_bus_type.rwsem); | ||
1659 | #endif | ||
1660 | } | 1621 | } |
1661 | } | 1622 | } |
1662 | } | 1623 | } |
1663 | 1624 | ||
1664 | /* | 1625 | /* we only change a device's upstream USB link. |
1665 | * FIXME this needs port power off call paths too, to help force | 1626 | * root hubs have no upstream USB link. |
1666 | * USB into the "generic" PM model. At least for devices on | ||
1667 | * ports that aren't using ganged switching (usually root hubs). | ||
1668 | * | ||
1669 | * NOTE: SRP-capable links should adopt more aggressive poweroff | ||
1670 | * policies (when HNP doesn't apply) once we have mechanisms to | ||
1671 | * turn power back on! (Likely not before 2.7...) | ||
1672 | */ | 1627 | */ |
1673 | if (state.event > PM_EVENT_FREEZE) { | 1628 | if (udev->parent) |
1674 | dev_warn(&udev->dev, "no poweroff yet, suspending instead\n"); | ||
1675 | } | ||
1676 | |||
1677 | /* "global suspend" of the HC-to-USB interface (root hub), or | ||
1678 | * "selective suspend" of just one hub-device link. | ||
1679 | */ | ||
1680 | if (!udev->parent) { | ||
1681 | struct usb_bus *bus = udev->bus; | ||
1682 | if (bus && bus->op->hub_suspend) { | ||
1683 | status = bus->op->hub_suspend (bus); | ||
1684 | if (status == 0) { | ||
1685 | dev_dbg(&udev->dev, "usb suspend\n"); | ||
1686 | usb_set_device_state(udev, | ||
1687 | USB_STATE_SUSPENDED); | ||
1688 | } | ||
1689 | } else | ||
1690 | status = -EOPNOTSUPP; | ||
1691 | } else | ||
1692 | status = hub_port_suspend(hdev_to_hub(udev->parent), port1, | 1629 | status = hub_port_suspend(hdev_to_hub(udev->parent), port1, |
1693 | udev); | 1630 | udev); |
1694 | 1631 | ||
1695 | if (status == 0) | 1632 | if (status == 0) |
1696 | udev->dev.power.power_state = state; | 1633 | udev->dev.power.power_state = PMSG_SUSPEND; |
1697 | return status; | 1634 | return status; |
1698 | } | 1635 | } |
1699 | 1636 | ||
1700 | /** | 1637 | #endif |
1638 | |||
1639 | /* | ||
1701 | * usb_suspend_device - suspend a usb device | 1640 | * usb_suspend_device - suspend a usb device |
1702 | * @udev: device that's no longer in active use | 1641 | * @udev: device that's no longer in active use |
1703 | * @state: PMSG_SUSPEND to suspend | 1642 | * Context: must be able to sleep; device not locked; pm locks held |
1704 | * Context: must be able to sleep; device not locked | ||
1705 | * | 1643 | * |
1706 | * Suspends a USB device that isn't in active use, conserving power. | 1644 | * Suspends a USB device that isn't in active use, conserving power. |
1707 | * Devices may wake out of a suspend, if anything important happens, | 1645 | * Devices may wake out of a suspend, if anything important happens, |
@@ -1709,37 +1647,50 @@ static int __usb_suspend_device (struct usb_device *udev, int port1, | |||
1709 | * suspend by the host, using usb_resume_device(). It's also routine | 1647 | * suspend by the host, using usb_resume_device(). It's also routine |
1710 | * to disconnect devices while they are suspended. | 1648 | * to disconnect devices while they are suspended. |
1711 | * | 1649 | * |
1650 | * This only affects the USB hardware for a device; its interfaces | ||
1651 | * (and, for hubs, child devices) must already have been suspended. | ||
1652 | * | ||
1712 | * Suspending OTG devices may trigger HNP, if that's been enabled | 1653 | * Suspending OTG devices may trigger HNP, if that's been enabled |
1713 | * between a pair of dual-role devices. That will change roles, such | 1654 | * between a pair of dual-role devices. That will change roles, such |
1714 | * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral. | 1655 | * as from A-Host to A-Peripheral or from B-Host back to B-Peripheral. |
1715 | * | 1656 | * |
1716 | * Returns 0 on success, else negative errno. | 1657 | * Returns 0 on success, else negative errno. |
1717 | */ | 1658 | */ |
1718 | int usb_suspend_device(struct usb_device *udev, pm_message_t state) | 1659 | int usb_suspend_device(struct usb_device *udev) |
1719 | { | 1660 | { |
1661 | #ifdef CONFIG_USB_SUSPEND | ||
1720 | int port1, status; | 1662 | int port1, status; |
1721 | 1663 | ||
1722 | port1 = locktree(udev); | 1664 | port1 = locktree(udev); |
1723 | if (port1 < 0) | 1665 | if (port1 < 0) |
1724 | return port1; | 1666 | return port1; |
1725 | 1667 | ||
1726 | status = __usb_suspend_device(udev, port1, state); | 1668 | status = __usb_suspend_device(udev, port1); |
1727 | usb_unlock_device(udev); | 1669 | usb_unlock_device(udev); |
1728 | return status; | 1670 | return status; |
1671 | #else | ||
1672 | /* NOTE: udev->state unchanged, it's not lying ... */ | ||
1673 | udev->dev.power.power_state = PMSG_SUSPEND; | ||
1674 | return 0; | ||
1675 | #endif | ||
1729 | } | 1676 | } |
1677 | EXPORT_SYMBOL_GPL(usb_suspend_device); | ||
1730 | 1678 | ||
1731 | /* | 1679 | /* |
1680 | * If the USB "suspend" state is in use (rather than "global suspend"), | ||
1681 | * many devices will be individually taken out of suspend state using | ||
1682 | * special" resume" signaling. These routines kick in shortly after | ||
1732 | * hardware resume signaling is finished, either because of selective | 1683 | * hardware resume signaling is finished, either because of selective |
1733 | * resume (by host) or remote wakeup (by device) ... now see what changed | 1684 | * resume (by host) or remote wakeup (by device) ... now see what changed |
1734 | * in the tree that's rooted at this device. | 1685 | * in the tree that's rooted at this device. |
1735 | */ | 1686 | */ |
1736 | static int finish_port_resume(struct usb_device *udev) | 1687 | static int finish_device_resume(struct usb_device *udev) |
1737 | { | 1688 | { |
1738 | int status; | 1689 | int status; |
1739 | u16 devstatus; | 1690 | u16 devstatus; |
1740 | 1691 | ||
1741 | /* caller owns the udev device lock */ | 1692 | /* caller owns the udev device lock */ |
1742 | dev_dbg(&udev->dev, "usb resume\n"); | 1693 | dev_dbg(&udev->dev, "finish resume\n"); |
1743 | 1694 | ||
1744 | /* usb ch9 identifies four variants of SUSPENDED, based on what | 1695 | /* usb ch9 identifies four variants of SUSPENDED, based on what |
1745 | * state the device resumes to. Linux currently won't see the | 1696 | * state the device resumes to. Linux currently won't see the |
@@ -1749,7 +1700,6 @@ static int finish_port_resume(struct usb_device *udev) | |||
1749 | usb_set_device_state(udev, udev->actconfig | 1700 | usb_set_device_state(udev, udev->actconfig |
1750 | ? USB_STATE_CONFIGURED | 1701 | ? USB_STATE_CONFIGURED |
1751 | : USB_STATE_ADDRESS); | 1702 | : USB_STATE_ADDRESS); |
1752 | udev->dev.power.power_state = PMSG_ON; | ||
1753 | 1703 | ||
1754 | /* 10.5.4.5 says be sure devices in the tree are still there. | 1704 | /* 10.5.4.5 says be sure devices in the tree are still there. |
1755 | * For now let's assume the device didn't go crazy on resume, | 1705 | * For now let's assume the device didn't go crazy on resume, |
@@ -1762,9 +1712,11 @@ static int finish_port_resume(struct usb_device *udev) | |||
1762 | status); | 1712 | status); |
1763 | else if (udev->actconfig) { | 1713 | else if (udev->actconfig) { |
1764 | unsigned i; | 1714 | unsigned i; |
1715 | int (*resume)(struct device *); | ||
1765 | 1716 | ||
1766 | le16_to_cpus(&devstatus); | 1717 | le16_to_cpus(&devstatus); |
1767 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { | 1718 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) |
1719 | && udev->parent) { | ||
1768 | status = usb_control_msg(udev, | 1720 | status = usb_control_msg(udev, |
1769 | usb_sndctrlpipe(udev, 0), | 1721 | usb_sndctrlpipe(udev, 0), |
1770 | USB_REQ_CLEAR_FEATURE, | 1722 | USB_REQ_CLEAR_FEATURE, |
@@ -1780,33 +1732,11 @@ static int finish_port_resume(struct usb_device *udev) | |||
1780 | } | 1732 | } |
1781 | 1733 | ||
1782 | /* resume interface drivers; if this is a hub, it | 1734 | /* resume interface drivers; if this is a hub, it |
1783 | * resumes the child devices | 1735 | * may have a child resume event to deal with soon |
1784 | */ | 1736 | */ |
1785 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 1737 | resume = udev->dev.bus->resume; |
1786 | struct usb_interface *intf; | 1738 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) |
1787 | struct usb_driver *driver; | 1739 | (void) resume(&udev->actconfig->interface[i]->dev); |
1788 | |||
1789 | intf = udev->actconfig->interface[i]; | ||
1790 | if (intf->dev.power.power_state.event == PM_EVENT_ON) | ||
1791 | continue; | ||
1792 | if (!intf->dev.driver) { | ||
1793 | /* FIXME maybe force to alt 0 */ | ||
1794 | continue; | ||
1795 | } | ||
1796 | driver = to_usb_driver(intf->dev.driver); | ||
1797 | |||
1798 | /* bus_rescan_devices() may rebind drivers */ | ||
1799 | if (!driver->resume) | ||
1800 | continue; | ||
1801 | |||
1802 | /* can we do better than just logging errors? */ | ||
1803 | status = driver->resume(intf); | ||
1804 | if (intf->dev.power.power_state.event != PM_EVENT_ON | ||
1805 | || status) | ||
1806 | dev_dbg(&intf->dev, | ||
1807 | "resume fail, state %d code %d\n", | ||
1808 | intf->dev.power.power_state.event, status); | ||
1809 | } | ||
1810 | status = 0; | 1740 | status = 0; |
1811 | 1741 | ||
1812 | } else if (udev->devnum <= 0) { | 1742 | } else if (udev->devnum <= 0) { |
@@ -1816,6 +1746,8 @@ static int finish_port_resume(struct usb_device *udev) | |||
1816 | return status; | 1746 | return status; |
1817 | } | 1747 | } |
1818 | 1748 | ||
1749 | #ifdef CONFIG_USB_SUSPEND | ||
1750 | |||
1819 | static int | 1751 | static int |
1820 | hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | 1752 | hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) |
1821 | { | 1753 | { |
@@ -1861,7 +1793,7 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
1861 | /* TRSMRCY = 10 msec */ | 1793 | /* TRSMRCY = 10 msec */ |
1862 | msleep(10); | 1794 | msleep(10); |
1863 | if (udev) | 1795 | if (udev) |
1864 | status = finish_port_resume(udev); | 1796 | status = finish_device_resume(udev); |
1865 | } | 1797 | } |
1866 | } | 1798 | } |
1867 | if (status < 0) | 1799 | if (status < 0) |
@@ -1870,12 +1802,12 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
1870 | return status; | 1802 | return status; |
1871 | } | 1803 | } |
1872 | 1804 | ||
1873 | static int hub_resume (struct usb_interface *intf); | 1805 | #endif |
1874 | 1806 | ||
1875 | /** | 1807 | /* |
1876 | * usb_resume_device - re-activate a suspended usb device | 1808 | * usb_resume_device - re-activate a suspended usb device |
1877 | * @udev: device to re-activate | 1809 | * @udev: device to re-activate |
1878 | * Context: must be able to sleep; device not locked | 1810 | * Context: must be able to sleep; device not locked; pm locks held |
1879 | * | 1811 | * |
1880 | * This will re-activate the suspended device, increasing power usage | 1812 | * This will re-activate the suspended device, increasing power usage |
1881 | * while letting drivers communicate again with its endpoints. | 1813 | * while letting drivers communicate again with its endpoints. |
@@ -1893,35 +1825,22 @@ int usb_resume_device(struct usb_device *udev) | |||
1893 | if (port1 < 0) | 1825 | if (port1 < 0) |
1894 | return port1; | 1826 | return port1; |
1895 | 1827 | ||
1896 | /* "global resume" of the HC-to-USB interface (root hub), or | 1828 | #ifdef CONFIG_USB_SUSPEND |
1897 | * selective resume of one hub-to-device port | 1829 | /* selective resume of one downstream hub-to-device port */ |
1898 | */ | 1830 | if (udev->parent) { |
1899 | if (!udev->parent) { | 1831 | if (udev->state == USB_STATE_SUSPENDED) { |
1900 | struct usb_bus *bus = udev->bus; | 1832 | // NOTE swsusp may bork us, device state being wrong... |
1901 | if (bus && bus->op->hub_resume) { | 1833 | // NOTE this fails if parent is also suspended... |
1902 | status = bus->op->hub_resume (bus); | 1834 | status = hub_port_resume(hdev_to_hub(udev->parent), |
1835 | port1, udev); | ||
1903 | } else | 1836 | } else |
1904 | status = -EOPNOTSUPP; | 1837 | status = 0; |
1905 | if (status == 0) { | 1838 | } else |
1906 | dev_dbg(&udev->dev, "usb resume\n"); | 1839 | #endif |
1907 | /* TRSMRCY = 10 msec */ | 1840 | status = finish_device_resume(udev); |
1908 | msleep(10); | 1841 | if (status < 0) |
1909 | usb_set_device_state (udev, USB_STATE_CONFIGURED); | ||
1910 | udev->dev.power.power_state = PMSG_ON; | ||
1911 | status = hub_resume (udev | ||
1912 | ->actconfig->interface[0]); | ||
1913 | } | ||
1914 | } else if (udev->state == USB_STATE_SUSPENDED) { | ||
1915 | // NOTE this fails if parent is also suspended... | ||
1916 | status = hub_port_resume(hdev_to_hub(udev->parent), | ||
1917 | port1, udev); | ||
1918 | } else { | ||
1919 | status = 0; | ||
1920 | } | ||
1921 | if (status < 0) { | ||
1922 | dev_dbg(&udev->dev, "can't resume, status %d\n", | 1842 | dev_dbg(&udev->dev, "can't resume, status %d\n", |
1923 | status); | 1843 | status); |
1924 | } | ||
1925 | 1844 | ||
1926 | usb_unlock_device(udev); | 1845 | usb_unlock_device(udev); |
1927 | 1846 | ||
@@ -1938,6 +1857,8 @@ static int remote_wakeup(struct usb_device *udev) | |||
1938 | { | 1857 | { |
1939 | int status = 0; | 1858 | int status = 0; |
1940 | 1859 | ||
1860 | #ifdef CONFIG_USB_SUSPEND | ||
1861 | |||
1941 | /* don't repeat RESUME sequence if this device | 1862 | /* don't repeat RESUME sequence if this device |
1942 | * was already woken up by some other task | 1863 | * was already woken up by some other task |
1943 | */ | 1864 | */ |
@@ -1946,38 +1867,52 @@ static int remote_wakeup(struct usb_device *udev) | |||
1946 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); | 1867 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); |
1947 | /* TRSMRCY = 10 msec */ | 1868 | /* TRSMRCY = 10 msec */ |
1948 | msleep(10); | 1869 | msleep(10); |
1949 | status = finish_port_resume(udev); | 1870 | status = finish_device_resume(udev); |
1950 | } | 1871 | } |
1951 | up(&udev->serialize); | 1872 | up(&udev->serialize); |
1873 | #endif | ||
1952 | return status; | 1874 | return status; |
1953 | } | 1875 | } |
1954 | 1876 | ||
1955 | static int hub_suspend(struct usb_interface *intf, pm_message_t state) | 1877 | static int hub_suspend(struct usb_interface *intf, pm_message_t msg) |
1956 | { | 1878 | { |
1957 | struct usb_hub *hub = usb_get_intfdata (intf); | 1879 | struct usb_hub *hub = usb_get_intfdata (intf); |
1958 | struct usb_device *hdev = hub->hdev; | 1880 | struct usb_device *hdev = hub->hdev; |
1959 | unsigned port1; | 1881 | unsigned port1; |
1960 | int status; | ||
1961 | |||
1962 | /* stop khubd and related activity */ | ||
1963 | hub_quiesce(hub); | ||
1964 | 1882 | ||
1965 | /* then suspend every port */ | 1883 | /* fail if children aren't already suspended */ |
1966 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | 1884 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { |
1967 | struct usb_device *udev; | 1885 | struct usb_device *udev; |
1968 | 1886 | ||
1969 | udev = hdev->children [port1-1]; | 1887 | udev = hdev->children [port1-1]; |
1970 | if (!udev) | 1888 | if (udev && (udev->dev.power.power_state.event |
1971 | continue; | 1889 | == PM_EVENT_ON |
1972 | down(&udev->serialize); | 1890 | #ifdef CONFIG_USB_SUSPEND |
1973 | status = __usb_suspend_device(udev, port1, state); | 1891 | || udev->state != USB_STATE_SUSPENDED |
1974 | up(&udev->serialize); | 1892 | #endif |
1975 | if (status < 0) | 1893 | )) { |
1976 | dev_dbg(&intf->dev, "suspend port %d --> %d\n", | 1894 | dev_dbg(&intf->dev, "port %d nyet suspended\n", port1); |
1977 | port1, status); | 1895 | return -EBUSY; |
1896 | } | ||
1978 | } | 1897 | } |
1979 | 1898 | ||
1980 | intf->dev.power.power_state = state; | 1899 | /* "global suspend" of the downstream HC-to-USB interface */ |
1900 | if (!hdev->parent) { | ||
1901 | struct usb_bus *bus = hdev->bus; | ||
1902 | if (bus) { | ||
1903 | int status = hcd_bus_suspend (bus); | ||
1904 | |||
1905 | if (status != 0) { | ||
1906 | dev_dbg(&hdev->dev, "'global' suspend %d\n", | ||
1907 | status); | ||
1908 | return status; | ||
1909 | } | ||
1910 | } else | ||
1911 | return -EOPNOTSUPP; | ||
1912 | } | ||
1913 | |||
1914 | /* stop khubd and related activity */ | ||
1915 | hub_quiesce(hub); | ||
1981 | return 0; | 1916 | return 0; |
1982 | } | 1917 | } |
1983 | 1918 | ||
@@ -1985,11 +1920,35 @@ static int hub_resume(struct usb_interface *intf) | |||
1985 | { | 1920 | { |
1986 | struct usb_device *hdev = interface_to_usbdev(intf); | 1921 | struct usb_device *hdev = interface_to_usbdev(intf); |
1987 | struct usb_hub *hub = usb_get_intfdata (intf); | 1922 | struct usb_hub *hub = usb_get_intfdata (intf); |
1988 | unsigned port1; | ||
1989 | int status; | 1923 | int status; |
1990 | 1924 | ||
1991 | if (intf->dev.power.power_state.event == PM_EVENT_ON) | 1925 | /* "global resume" of the downstream HC-to-USB interface */ |
1992 | return 0; | 1926 | if (!hdev->parent) { |
1927 | struct usb_bus *bus = hdev->bus; | ||
1928 | if (bus) { | ||
1929 | status = hcd_bus_resume (bus); | ||
1930 | if (status) { | ||
1931 | dev_dbg(&intf->dev, "'global' resume %d\n", | ||
1932 | status); | ||
1933 | return status; | ||
1934 | } | ||
1935 | } else | ||
1936 | return -EOPNOTSUPP; | ||
1937 | if (status == 0) { | ||
1938 | /* TRSMRCY = 10 msec */ | ||
1939 | msleep(10); | ||
1940 | } | ||
1941 | } | ||
1942 | |||
1943 | hub_activate(hub); | ||
1944 | |||
1945 | /* REVISIT: this recursion probably shouldn't exist. Remove | ||
1946 | * this code sometime, after retesting with different root and | ||
1947 | * external hubs. | ||
1948 | */ | ||
1949 | #ifdef CONFIG_USB_SUSPEND | ||
1950 | { | ||
1951 | unsigned port1; | ||
1993 | 1952 | ||
1994 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | 1953 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { |
1995 | struct usb_device *udev; | 1954 | struct usb_device *udev; |
@@ -2015,7 +1974,7 @@ static int hub_resume(struct usb_interface *intf) | |||
2015 | if (portstat & USB_PORT_STAT_SUSPEND) | 1974 | if (portstat & USB_PORT_STAT_SUSPEND) |
2016 | status = hub_port_resume(hub, port1, udev); | 1975 | status = hub_port_resume(hub, port1, udev); |
2017 | else { | 1976 | else { |
2018 | status = finish_port_resume(udev); | 1977 | status = finish_device_resume(udev); |
2019 | if (status < 0) { | 1978 | if (status < 0) { |
2020 | dev_dbg(&intf->dev, "resume port %d --> %d\n", | 1979 | dev_dbg(&intf->dev, "resume port %d --> %d\n", |
2021 | port1, status); | 1980 | port1, status); |
@@ -2024,43 +1983,31 @@ static int hub_resume(struct usb_interface *intf) | |||
2024 | } | 1983 | } |
2025 | up(&udev->serialize); | 1984 | up(&udev->serialize); |
2026 | } | 1985 | } |
2027 | intf->dev.power.power_state = PMSG_ON; | 1986 | } |
2028 | 1987 | #endif | |
2029 | hub->resume_root_hub = 0; | ||
2030 | hub_activate(hub); | ||
2031 | return 0; | 1988 | return 0; |
2032 | } | 1989 | } |
2033 | 1990 | ||
2034 | void usb_resume_root_hub(struct usb_device *hdev) | 1991 | void usb_suspend_root_hub(struct usb_device *hdev) |
2035 | { | 1992 | { |
2036 | struct usb_hub *hub = hdev_to_hub(hdev); | 1993 | struct usb_hub *hub = hdev_to_hub(hdev); |
2037 | 1994 | ||
2038 | hub->resume_root_hub = 1; | 1995 | /* This also makes any led blinker stop retriggering. We're called |
2039 | kick_khubd(hub); | 1996 | * from irq, so the blinker might still be scheduled. Caller promises |
1997 | * that the root hub status URB will be canceled. | ||
1998 | */ | ||
1999 | __hub_quiesce(hub); | ||
2000 | mark_quiesced(to_usb_interface(hub->intfdev)); | ||
2040 | } | 2001 | } |
2041 | 2002 | ||
2042 | #else /* !CONFIG_USB_SUSPEND */ | 2003 | void usb_resume_root_hub(struct usb_device *hdev) |
2043 | |||
2044 | int usb_suspend_device(struct usb_device *udev, pm_message_t state) | ||
2045 | { | 2004 | { |
2046 | return 0; | 2005 | struct usb_hub *hub = hdev_to_hub(hdev); |
2047 | } | ||
2048 | 2006 | ||
2049 | int usb_resume_device(struct usb_device *udev) | 2007 | hub->resume_root_hub = 1; |
2050 | { | 2008 | kick_khubd(hub); |
2051 | return 0; | ||
2052 | } | 2009 | } |
2053 | 2010 | ||
2054 | #define hub_suspend NULL | ||
2055 | #define hub_resume NULL | ||
2056 | #define remote_wakeup(x) 0 | ||
2057 | |||
2058 | #endif /* CONFIG_USB_SUSPEND */ | ||
2059 | |||
2060 | EXPORT_SYMBOL(usb_suspend_device); | ||
2061 | EXPORT_SYMBOL(usb_resume_device); | ||
2062 | |||
2063 | |||
2064 | 2011 | ||
2065 | /* USB 2.0 spec, 7.1.7.3 / fig 7-29: | 2012 | /* USB 2.0 spec, 7.1.7.3 / fig 7-29: |
2066 | * | 2013 | * |
@@ -2469,6 +2416,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2469 | { | 2416 | { |
2470 | struct usb_device *hdev = hub->hdev; | 2417 | struct usb_device *hdev = hub->hdev; |
2471 | struct device *hub_dev = hub->intfdev; | 2418 | struct device *hub_dev = hub->intfdev; |
2419 | u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); | ||
2472 | int status, i; | 2420 | int status, i; |
2473 | 2421 | ||
2474 | dev_dbg (hub_dev, | 2422 | dev_dbg (hub_dev, |
@@ -2506,8 +2454,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2506 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) { | 2454 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) { |
2507 | 2455 | ||
2508 | /* maybe switch power back on (e.g. root hub was reset) */ | 2456 | /* maybe switch power back on (e.g. root hub was reset) */ |
2509 | if ((hub->descriptor->wHubCharacteristics | 2457 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 |
2510 | & HUB_CHAR_LPSM) < 2 | ||
2511 | && !(portstatus & (1 << USB_PORT_FEAT_POWER))) | 2458 | && !(portstatus & (1 << USB_PORT_FEAT_POWER))) |
2512 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); | 2459 | set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); |
2513 | 2460 | ||
@@ -2686,21 +2633,28 @@ static void hub_events(void) | |||
2686 | intf = to_usb_interface(hub->intfdev); | 2633 | intf = to_usb_interface(hub->intfdev); |
2687 | hub_dev = &intf->dev; | 2634 | hub_dev = &intf->dev; |
2688 | 2635 | ||
2689 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x\n", | 2636 | i = hub->resume_root_hub; |
2637 | |||
2638 | dev_dbg(hub_dev, "state %d ports %d chg %04x evt %04x%s\n", | ||
2690 | hdev->state, hub->descriptor | 2639 | hdev->state, hub->descriptor |
2691 | ? hub->descriptor->bNbrPorts | 2640 | ? hub->descriptor->bNbrPorts |
2692 | : 0, | 2641 | : 0, |
2693 | /* NOTE: expects max 15 ports... */ | 2642 | /* NOTE: expects max 15 ports... */ |
2694 | (u16) hub->change_bits[0], | 2643 | (u16) hub->change_bits[0], |
2695 | (u16) hub->event_bits[0]); | 2644 | (u16) hub->event_bits[0], |
2645 | i ? ", resume root" : ""); | ||
2696 | 2646 | ||
2697 | usb_get_intf(intf); | 2647 | usb_get_intf(intf); |
2698 | i = hub->resume_root_hub; | ||
2699 | spin_unlock_irq(&hub_event_lock); | 2648 | spin_unlock_irq(&hub_event_lock); |
2700 | 2649 | ||
2701 | /* Is this is a root hub wanting to be resumed? */ | 2650 | /* Is this is a root hub wanting to reactivate the downstream |
2702 | if (i) | 2651 | * ports? If so, be sure the interface resumes even if its |
2703 | usb_resume_device(hdev); | 2652 | * stub "device" node was never suspended. |
2653 | */ | ||
2654 | if (i) { | ||
2655 | dpm_runtime_resume(&hdev->dev); | ||
2656 | dpm_runtime_resume(&intf->dev); | ||
2657 | } | ||
2704 | 2658 | ||
2705 | /* Lock the device, then check to see if we were | 2659 | /* Lock the device, then check to see if we were |
2706 | * disconnected while waiting for the lock to succeed. */ | 2660 | * disconnected while waiting for the lock to succeed. */ |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index e7fa9b5a521e..bf23f8978024 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -131,7 +131,7 @@ struct usb_hub_descriptor { | |||
131 | __u8 bDescLength; | 131 | __u8 bDescLength; |
132 | __u8 bDescriptorType; | 132 | __u8 bDescriptorType; |
133 | __u8 bNbrPorts; | 133 | __u8 bNbrPorts; |
134 | __u16 wHubCharacteristics; | 134 | __le16 wHubCharacteristics; |
135 | __u8 bPwrOn2PwrGood; | 135 | __u8 bPwrOn2PwrGood; |
136 | __u8 bHubContrCurrent; | 136 | __u8 bHubContrCurrent; |
137 | /* add 1 bit for hub status change; round to bytes */ | 137 | /* add 1 bit for hub status change; round to bytes */ |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index d07bba01995b..12f490fdee8f 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/usbdevice_fs.h> | 39 | #include <linux/usbdevice_fs.h> |
40 | #include <linux/smp_lock.h> | 40 | #include <linux/smp_lock.h> |
41 | #include <linux/parser.h> | 41 | #include <linux/parser.h> |
42 | #include <linux/notifier.h> | ||
42 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
43 | #include "usb.h" | 44 | #include "usb.h" |
44 | #include "hcd.h" | 45 | #include "hcd.h" |
@@ -619,7 +620,7 @@ void usbfs_update_special (void) | |||
619 | } | 620 | } |
620 | } | 621 | } |
621 | 622 | ||
622 | void usbfs_add_bus(struct usb_bus *bus) | 623 | static void usbfs_add_bus(struct usb_bus *bus) |
623 | { | 624 | { |
624 | struct dentry *parent; | 625 | struct dentry *parent; |
625 | char name[8]; | 626 | char name[8]; |
@@ -642,12 +643,9 @@ void usbfs_add_bus(struct usb_bus *bus) | |||
642 | err ("error creating usbfs bus entry"); | 643 | err ("error creating usbfs bus entry"); |
643 | return; | 644 | return; |
644 | } | 645 | } |
645 | |||
646 | usbfs_update_special(); | ||
647 | usbfs_conn_disc_event(); | ||
648 | } | 646 | } |
649 | 647 | ||
650 | void usbfs_remove_bus(struct usb_bus *bus) | 648 | static void usbfs_remove_bus(struct usb_bus *bus) |
651 | { | 649 | { |
652 | if (bus->usbfs_dentry) { | 650 | if (bus->usbfs_dentry) { |
653 | fs_remove_file (bus->usbfs_dentry); | 651 | fs_remove_file (bus->usbfs_dentry); |
@@ -659,12 +657,9 @@ void usbfs_remove_bus(struct usb_bus *bus) | |||
659 | remove_special_files(); | 657 | remove_special_files(); |
660 | num_buses = 0; | 658 | num_buses = 0; |
661 | } | 659 | } |
662 | |||
663 | usbfs_update_special(); | ||
664 | usbfs_conn_disc_event(); | ||
665 | } | 660 | } |
666 | 661 | ||
667 | void usbfs_add_device(struct usb_device *dev) | 662 | static void usbfs_add_device(struct usb_device *dev) |
668 | { | 663 | { |
669 | char name[8]; | 664 | char name[8]; |
670 | int i; | 665 | int i; |
@@ -690,12 +685,9 @@ void usbfs_add_device(struct usb_device *dev) | |||
690 | } | 685 | } |
691 | if (dev->usbfs_dentry->d_inode) | 686 | if (dev->usbfs_dentry->d_inode) |
692 | dev->usbfs_dentry->d_inode->i_size = i_size; | 687 | dev->usbfs_dentry->d_inode->i_size = i_size; |
693 | |||
694 | usbfs_update_special(); | ||
695 | usbfs_conn_disc_event(); | ||
696 | } | 688 | } |
697 | 689 | ||
698 | void usbfs_remove_device(struct usb_device *dev) | 690 | static void usbfs_remove_device(struct usb_device *dev) |
699 | { | 691 | { |
700 | struct dev_state *ds; | 692 | struct dev_state *ds; |
701 | struct siginfo sinfo; | 693 | struct siginfo sinfo; |
@@ -716,10 +708,33 @@ void usbfs_remove_device(struct usb_device *dev) | |||
716 | kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid); | 708 | kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid); |
717 | } | 709 | } |
718 | } | 710 | } |
711 | } | ||
712 | |||
713 | static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) | ||
714 | { | ||
715 | switch (action) { | ||
716 | case USB_DEVICE_ADD: | ||
717 | usbfs_add_device(dev); | ||
718 | break; | ||
719 | case USB_DEVICE_REMOVE: | ||
720 | usbfs_remove_device(dev); | ||
721 | break; | ||
722 | case USB_BUS_ADD: | ||
723 | usbfs_add_bus(dev); | ||
724 | break; | ||
725 | case USB_BUS_REMOVE: | ||
726 | usbfs_remove_bus(dev); | ||
727 | } | ||
728 | |||
719 | usbfs_update_special(); | 729 | usbfs_update_special(); |
720 | usbfs_conn_disc_event(); | 730 | usbfs_conn_disc_event(); |
731 | return NOTIFY_OK; | ||
721 | } | 732 | } |
722 | 733 | ||
734 | static struct notifier_block usbfs_nb = { | ||
735 | .notifier_call = usbfs_notify, | ||
736 | }; | ||
737 | |||
723 | /* --------------------------------------------------------------------- */ | 738 | /* --------------------------------------------------------------------- */ |
724 | 739 | ||
725 | static struct proc_dir_entry *usbdir = NULL; | 740 | static struct proc_dir_entry *usbdir = NULL; |
@@ -732,6 +747,8 @@ int __init usbfs_init(void) | |||
732 | if (retval) | 747 | if (retval) |
733 | return retval; | 748 | return retval; |
734 | 749 | ||
750 | usb_register_notify(&usbfs_nb); | ||
751 | |||
735 | /* create mount point for usbfs */ | 752 | /* create mount point for usbfs */ |
736 | usbdir = proc_mkdir("usb", proc_bus); | 753 | usbdir = proc_mkdir("usb", proc_bus); |
737 | 754 | ||
@@ -740,6 +757,7 @@ int __init usbfs_init(void) | |||
740 | 757 | ||
741 | void usbfs_cleanup(void) | 758 | void usbfs_cleanup(void) |
742 | { | 759 | { |
760 | usb_unregister_notify(&usbfs_nb); | ||
743 | unregister_filesystem(&usb_fs_type); | 761 | unregister_filesystem(&usb_fs_type); |
744 | if (usbdir) | 762 | if (usbdir) |
745 | remove_proc_entry("usb", proc_bus); | 763 | remove_proc_entry("usb", proc_bus); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f9a81e84dbdf..644a3d4f12aa 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -187,21 +187,37 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u | |||
187 | * If a thread in your driver uses this call, make sure your disconnect() | 187 | * If a thread in your driver uses this call, make sure your disconnect() |
188 | * method can wait for it to complete. Since you don't have a handle on | 188 | * method can wait for it to complete. Since you don't have a handle on |
189 | * the URB used, you can't cancel the request. | 189 | * the URB used, you can't cancel the request. |
190 | * | ||
191 | * Because there is no usb_interrupt_msg() and no USBDEVFS_INTERRUPT | ||
192 | * ioctl, users are forced to abuse this routine by using it to submit | ||
193 | * URBs for interrupt endpoints. We will take the liberty of creating | ||
194 | * an interrupt URB (with the default interval) if the target is an | ||
195 | * interrupt endpoint. | ||
190 | */ | 196 | */ |
191 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, | 197 | int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, |
192 | void *data, int len, int *actual_length, int timeout) | 198 | void *data, int len, int *actual_length, int timeout) |
193 | { | 199 | { |
194 | struct urb *urb; | 200 | struct urb *urb; |
201 | struct usb_host_endpoint *ep; | ||
195 | 202 | ||
196 | if (len < 0) | 203 | ep = (usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out) |
204 | [usb_pipeendpoint(pipe)]; | ||
205 | if (!ep || len < 0) | ||
197 | return -EINVAL; | 206 | return -EINVAL; |
198 | 207 | ||
199 | urb=usb_alloc_urb(0, GFP_KERNEL); | 208 | urb = usb_alloc_urb(0, GFP_KERNEL); |
200 | if (!urb) | 209 | if (!urb) |
201 | return -ENOMEM; | 210 | return -ENOMEM; |
202 | 211 | ||
203 | usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, | 212 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == |
204 | usb_api_blocking_completion, NULL); | 213 | USB_ENDPOINT_XFER_INT) { |
214 | pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); | ||
215 | usb_fill_int_urb(urb, usb_dev, pipe, data, len, | ||
216 | usb_api_blocking_completion, NULL, | ||
217 | ep->desc.bInterval); | ||
218 | } else | ||
219 | usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, | ||
220 | usb_api_blocking_completion, NULL); | ||
205 | 221 | ||
206 | return usb_start_wait_urb(urb, timeout, actual_length); | 222 | return usb_start_wait_urb(urb, timeout, actual_length); |
207 | } | 223 | } |
@@ -771,6 +787,31 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
771 | return err; | 787 | return err; |
772 | } | 788 | } |
773 | 789 | ||
790 | /** | ||
791 | * usb_cache_string - read a string descriptor and cache it for later use | ||
792 | * @udev: the device whose string descriptor is being read | ||
793 | * @index: the descriptor index | ||
794 | * | ||
795 | * Returns a pointer to a kmalloc'ed buffer containing the descriptor string, | ||
796 | * or NULL if the index is 0 or the string could not be read. | ||
797 | */ | ||
798 | char *usb_cache_string(struct usb_device *udev, int index) | ||
799 | { | ||
800 | char *buf; | ||
801 | char *smallbuf = NULL; | ||
802 | int len; | ||
803 | |||
804 | if (index > 0 && (buf = kmalloc(256, GFP_KERNEL)) != NULL) { | ||
805 | if ((len = usb_string(udev, index, buf, 256)) > 0) { | ||
806 | if ((smallbuf = kmalloc(++len, GFP_KERNEL)) == NULL) | ||
807 | return buf; | ||
808 | memcpy(smallbuf, buf, len); | ||
809 | } | ||
810 | kfree(buf); | ||
811 | } | ||
812 | return smallbuf; | ||
813 | } | ||
814 | |||
774 | /* | 815 | /* |
775 | * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) | 816 | * usb_get_device_descriptor - (re)reads the device descriptor (usbcore) |
776 | * @dev: the device whose device descriptor is being updated | 817 | * @dev: the device whose device descriptor is being updated |
@@ -992,8 +1033,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
992 | dev_dbg (&dev->dev, "unregistering interface %s\n", | 1033 | dev_dbg (&dev->dev, "unregistering interface %s\n", |
993 | interface->dev.bus_id); | 1034 | interface->dev.bus_id); |
994 | usb_remove_sysfs_intf_files(interface); | 1035 | usb_remove_sysfs_intf_files(interface); |
995 | kfree(interface->cur_altsetting->string); | ||
996 | interface->cur_altsetting->string = NULL; | ||
997 | device_del (&interface->dev); | 1036 | device_del (&interface->dev); |
998 | } | 1037 | } |
999 | 1038 | ||
@@ -1133,6 +1172,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1133 | */ | 1172 | */ |
1134 | 1173 | ||
1135 | /* prevent submissions using previous endpoint settings */ | 1174 | /* prevent submissions using previous endpoint settings */ |
1175 | if (device_is_registered(&iface->dev)) | ||
1176 | usb_remove_sysfs_intf_files(iface); | ||
1136 | usb_disable_interface(dev, iface); | 1177 | usb_disable_interface(dev, iface); |
1137 | 1178 | ||
1138 | iface->cur_altsetting = alt; | 1179 | iface->cur_altsetting = alt; |
@@ -1168,6 +1209,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1168 | * (Likewise, EP0 never "halts" on well designed devices.) | 1209 | * (Likewise, EP0 never "halts" on well designed devices.) |
1169 | */ | 1210 | */ |
1170 | usb_enable_interface(dev, iface); | 1211 | usb_enable_interface(dev, iface); |
1212 | if (device_is_registered(&iface->dev)) | ||
1213 | usb_create_sysfs_intf_files(iface); | ||
1171 | 1214 | ||
1172 | return 0; | 1215 | return 0; |
1173 | } | 1216 | } |
@@ -1217,10 +1260,8 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1217 | USB_REQ_SET_CONFIGURATION, 0, | 1260 | USB_REQ_SET_CONFIGURATION, 0, |
1218 | config->desc.bConfigurationValue, 0, | 1261 | config->desc.bConfigurationValue, 0, |
1219 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 1262 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
1220 | if (retval < 0) { | 1263 | if (retval < 0) |
1221 | usb_set_device_state(dev, USB_STATE_ADDRESS); | ||
1222 | return retval; | 1264 | return retval; |
1223 | } | ||
1224 | 1265 | ||
1225 | dev->toggle[0] = dev->toggle[1] = 0; | 1266 | dev->toggle[0] = dev->toggle[1] = 0; |
1226 | 1267 | ||
@@ -1229,6 +1270,8 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1229 | struct usb_interface *intf = config->interface[i]; | 1270 | struct usb_interface *intf = config->interface[i]; |
1230 | struct usb_host_interface *alt; | 1271 | struct usb_host_interface *alt; |
1231 | 1272 | ||
1273 | if (device_is_registered(&intf->dev)) | ||
1274 | usb_remove_sysfs_intf_files(intf); | ||
1232 | alt = usb_altnum_to_altsetting(intf, 0); | 1275 | alt = usb_altnum_to_altsetting(intf, 0); |
1233 | 1276 | ||
1234 | /* No altsetting 0? We'll assume the first altsetting. | 1277 | /* No altsetting 0? We'll assume the first altsetting. |
@@ -1241,6 +1284,8 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1241 | 1284 | ||
1242 | intf->cur_altsetting = alt; | 1285 | intf->cur_altsetting = alt; |
1243 | usb_enable_interface(dev, intf); | 1286 | usb_enable_interface(dev, intf); |
1287 | if (device_is_registered(&intf->dev)) | ||
1288 | usb_create_sysfs_intf_files(intf); | ||
1244 | } | 1289 | } |
1245 | return 0; | 1290 | return 0; |
1246 | } | 1291 | } |
@@ -1328,7 +1373,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1328 | } | 1373 | } |
1329 | 1374 | ||
1330 | for (; n < nintf; ++n) { | 1375 | for (; n < nintf; ++n) { |
1331 | new_interfaces[n] = kmalloc( | 1376 | new_interfaces[n] = kzalloc( |
1332 | sizeof(struct usb_interface), | 1377 | sizeof(struct usb_interface), |
1333 | GFP_KERNEL); | 1378 | GFP_KERNEL); |
1334 | if (!new_interfaces[n]) { | 1379 | if (!new_interfaces[n]) { |
@@ -1369,7 +1414,6 @@ free_interfaces: | |||
1369 | struct usb_host_interface *alt; | 1414 | struct usb_host_interface *alt; |
1370 | 1415 | ||
1371 | cp->interface[i] = intf = new_interfaces[i]; | 1416 | cp->interface[i] = intf = new_interfaces[i]; |
1372 | memset(intf, 0, sizeof(*intf)); | ||
1373 | intfc = cp->intf_cache[i]; | 1417 | intfc = cp->intf_cache[i]; |
1374 | intf->altsetting = intfc->altsetting; | 1418 | intf->altsetting = intfc->altsetting; |
1375 | intf->num_altsetting = intfc->num_altsetting; | 1419 | intf->num_altsetting = intfc->num_altsetting; |
@@ -1393,6 +1437,7 @@ free_interfaces: | |||
1393 | intf->dev.dma_mask = dev->dev.dma_mask; | 1437 | intf->dev.dma_mask = dev->dev.dma_mask; |
1394 | intf->dev.release = release_interface; | 1438 | intf->dev.release = release_interface; |
1395 | device_initialize (&intf->dev); | 1439 | device_initialize (&intf->dev); |
1440 | mark_quiesced(intf); | ||
1396 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", | 1441 | sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", |
1397 | dev->bus->busnum, dev->devpath, | 1442 | dev->bus->busnum, dev->devpath, |
1398 | configuration, | 1443 | configuration, |
@@ -1400,12 +1445,9 @@ free_interfaces: | |||
1400 | } | 1445 | } |
1401 | kfree(new_interfaces); | 1446 | kfree(new_interfaces); |
1402 | 1447 | ||
1403 | if ((cp->desc.iConfiguration) && | 1448 | if (cp->string == NULL) |
1404 | (cp->string == NULL)) { | 1449 | cp->string = usb_cache_string(dev, |
1405 | cp->string = kmalloc(256, GFP_KERNEL); | 1450 | cp->desc.iConfiguration); |
1406 | if (cp->string) | ||
1407 | usb_string(dev, cp->desc.iConfiguration, cp->string, 256); | ||
1408 | } | ||
1409 | 1451 | ||
1410 | /* Now that all the interfaces are set up, register them | 1452 | /* Now that all the interfaces are set up, register them |
1411 | * to trigger binding of drivers to interfaces. probe() | 1453 | * to trigger binding of drivers to interfaces. probe() |
@@ -1415,13 +1457,12 @@ free_interfaces: | |||
1415 | */ | 1457 | */ |
1416 | for (i = 0; i < nintf; ++i) { | 1458 | for (i = 0; i < nintf; ++i) { |
1417 | struct usb_interface *intf = cp->interface[i]; | 1459 | struct usb_interface *intf = cp->interface[i]; |
1418 | struct usb_interface_descriptor *desc; | 1460 | struct usb_host_interface *alt = intf->cur_altsetting; |
1419 | 1461 | ||
1420 | desc = &intf->altsetting [0].desc; | ||
1421 | dev_dbg (&dev->dev, | 1462 | dev_dbg (&dev->dev, |
1422 | "adding %s (config #%d, interface %d)\n", | 1463 | "adding %s (config #%d, interface %d)\n", |
1423 | intf->dev.bus_id, configuration, | 1464 | intf->dev.bus_id, configuration, |
1424 | desc->bInterfaceNumber); | 1465 | alt->desc.bInterfaceNumber); |
1425 | ret = device_add (&intf->dev); | 1466 | ret = device_add (&intf->dev); |
1426 | if (ret != 0) { | 1467 | if (ret != 0) { |
1427 | dev_err(&dev->dev, | 1468 | dev_err(&dev->dev, |
@@ -1430,13 +1471,6 @@ free_interfaces: | |||
1430 | ret); | 1471 | ret); |
1431 | continue; | 1472 | continue; |
1432 | } | 1473 | } |
1433 | if ((intf->cur_altsetting->desc.iInterface) && | ||
1434 | (intf->cur_altsetting->string == NULL)) { | ||
1435 | intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL); | ||
1436 | if (intf->cur_altsetting->string) | ||
1437 | usb_string(dev, intf->cur_altsetting->desc.iInterface, | ||
1438 | intf->cur_altsetting->string, 256); | ||
1439 | } | ||
1440 | usb_create_sysfs_intf_files (intf); | 1474 | usb_create_sysfs_intf_files (intf); |
1441 | } | 1475 | } |
1442 | } | 1476 | } |
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c new file mode 100644 index 000000000000..37da059eced7 --- /dev/null +++ b/drivers/usb/core/notify.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * All the USB notify logic | ||
3 | * | ||
4 | * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * notifier functions originally based on those in kernel/sys.c | ||
7 | * but fixed up to not be so broken. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/notifier.h> | ||
15 | #ifdef CONFIG_USB_DEBUG | ||
16 | #define DEBUG | ||
17 | #else | ||
18 | #undef DEBUG | ||
19 | #endif | ||
20 | #include <linux/usb.h> | ||
21 | |||
22 | #include "usb.h" | ||
23 | |||
24 | |||
25 | static struct notifier_block *usb_notifier_list; | ||
26 | static DECLARE_MUTEX(usb_notifier_lock); | ||
27 | |||
28 | static void usb_notifier_chain_register(struct notifier_block **list, | ||
29 | struct notifier_block *n) | ||
30 | { | ||
31 | down(&usb_notifier_lock); | ||
32 | while (*list) { | ||
33 | if (n->priority > (*list)->priority) | ||
34 | break; | ||
35 | list = &((*list)->next); | ||
36 | } | ||
37 | n->next = *list; | ||
38 | *list = n; | ||
39 | up(&usb_notifier_lock); | ||
40 | } | ||
41 | |||
42 | static void usb_notifier_chain_unregister(struct notifier_block **nl, | ||
43 | struct notifier_block *n) | ||
44 | { | ||
45 | down(&usb_notifier_lock); | ||
46 | while ((*nl)!=NULL) { | ||
47 | if ((*nl)==n) { | ||
48 | *nl = n->next; | ||
49 | goto exit; | ||
50 | } | ||
51 | nl=&((*nl)->next); | ||
52 | } | ||
53 | exit: | ||
54 | up(&usb_notifier_lock); | ||
55 | } | ||
56 | |||
57 | static int usb_notifier_call_chain(struct notifier_block **n, | ||
58 | unsigned long val, void *v) | ||
59 | { | ||
60 | int ret=NOTIFY_DONE; | ||
61 | struct notifier_block *nb = *n; | ||
62 | |||
63 | down(&usb_notifier_lock); | ||
64 | while (nb) { | ||
65 | ret = nb->notifier_call(nb,val,v); | ||
66 | if (ret&NOTIFY_STOP_MASK) { | ||
67 | goto exit; | ||
68 | } | ||
69 | nb = nb->next; | ||
70 | } | ||
71 | exit: | ||
72 | up(&usb_notifier_lock); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * usb_register_notify - register a notifier callback whenever a usb change happens | ||
78 | * @nb: pointer to the notifier block for the callback events. | ||
79 | * | ||
80 | * These changes are either USB devices or busses being added or removed. | ||
81 | */ | ||
82 | void usb_register_notify(struct notifier_block *nb) | ||
83 | { | ||
84 | usb_notifier_chain_register(&usb_notifier_list, nb); | ||
85 | } | ||
86 | EXPORT_SYMBOL_GPL(usb_register_notify); | ||
87 | |||
88 | /** | ||
89 | * usb_unregister_notify - unregister a notifier callback | ||
90 | * @nb: pointer to the notifier block for the callback events. | ||
91 | * | ||
92 | * usb_register_notifier() must have been previously called for this function | ||
93 | * to work properly. | ||
94 | */ | ||
95 | void usb_unregister_notify(struct notifier_block *nb) | ||
96 | { | ||
97 | usb_notifier_chain_unregister(&usb_notifier_list, nb); | ||
98 | } | ||
99 | EXPORT_SYMBOL_GPL(usb_unregister_notify); | ||
100 | |||
101 | |||
102 | void usb_notify_add_device(struct usb_device *udev) | ||
103 | { | ||
104 | usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_ADD, udev); | ||
105 | } | ||
106 | |||
107 | void usb_notify_remove_device(struct usb_device *udev) | ||
108 | { | ||
109 | usb_notifier_call_chain(&usb_notifier_list, USB_DEVICE_REMOVE, udev); | ||
110 | } | ||
111 | |||
112 | void usb_notify_add_bus(struct usb_bus *ubus) | ||
113 | { | ||
114 | usb_notifier_call_chain(&usb_notifier_list, USB_BUS_ADD, ubus); | ||
115 | } | ||
116 | |||
117 | void usb_notify_remove_bus(struct usb_bus *ubus) | ||
118 | { | ||
119 | usb_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus); | ||
120 | } | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 00297f113849..edd83e014452 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -22,9 +22,207 @@ | |||
22 | 22 | ||
23 | #include "usb.h" | 23 | #include "usb.h" |
24 | 24 | ||
25 | /* endpoint stuff */ | ||
26 | struct ep_object { | ||
27 | struct usb_endpoint_descriptor *desc; | ||
28 | struct usb_device *udev; | ||
29 | struct kobject kobj; | ||
30 | }; | ||
31 | #define to_ep_object(_kobj) \ | ||
32 | container_of(_kobj, struct ep_object, kobj) | ||
33 | |||
34 | struct ep_attribute { | ||
35 | struct attribute attr; | ||
36 | ssize_t (*show)(struct usb_device *, | ||
37 | struct usb_endpoint_descriptor *, char *); | ||
38 | }; | ||
39 | #define to_ep_attribute(_attr) \ | ||
40 | container_of(_attr, struct ep_attribute, attr) | ||
41 | |||
42 | #define EP_ATTR(_name) \ | ||
43 | struct ep_attribute ep_##_name = { \ | ||
44 | .attr = {.name = #_name, .owner = THIS_MODULE, \ | ||
45 | .mode = S_IRUGO}, \ | ||
46 | .show = show_ep_##_name} | ||
47 | |||
48 | #define usb_ep_attr(field, format_string) \ | ||
49 | static ssize_t show_ep_##field(struct usb_device *udev, \ | ||
50 | struct usb_endpoint_descriptor *desc, \ | ||
51 | char *buf) \ | ||
52 | { \ | ||
53 | return sprintf(buf, format_string, desc->field); \ | ||
54 | } \ | ||
55 | static EP_ATTR(field); | ||
56 | |||
57 | usb_ep_attr(bLength, "%02x\n") | ||
58 | usb_ep_attr(bEndpointAddress, "%02x\n") | ||
59 | usb_ep_attr(bmAttributes, "%02x\n") | ||
60 | usb_ep_attr(bInterval, "%02x\n") | ||
61 | |||
62 | static ssize_t show_ep_wMaxPacketSize(struct usb_device *udev, | ||
63 | struct usb_endpoint_descriptor *desc, char *buf) | ||
64 | { | ||
65 | return sprintf(buf, "%04x\n", | ||
66 | le16_to_cpu(desc->wMaxPacketSize) & 0x07ff); | ||
67 | } | ||
68 | static EP_ATTR(wMaxPacketSize); | ||
69 | |||
70 | static ssize_t show_ep_type(struct usb_device *udev, | ||
71 | struct usb_endpoint_descriptor *desc, char *buf) | ||
72 | { | ||
73 | char *type = "unknown"; | ||
74 | |||
75 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
76 | case USB_ENDPOINT_XFER_CONTROL: | ||
77 | type = "Control"; | ||
78 | break; | ||
79 | case USB_ENDPOINT_XFER_ISOC: | ||
80 | type = "Isoc"; | ||
81 | break; | ||
82 | case USB_ENDPOINT_XFER_BULK: | ||
83 | type = "Bulk"; | ||
84 | break; | ||
85 | case USB_ENDPOINT_XFER_INT: | ||
86 | type = "Interrupt"; | ||
87 | break; | ||
88 | } | ||
89 | return sprintf(buf, "%s\n", type); | ||
90 | } | ||
91 | static EP_ATTR(type); | ||
92 | |||
93 | static ssize_t show_ep_interval(struct usb_device *udev, | ||
94 | struct usb_endpoint_descriptor *desc, char *buf) | ||
95 | { | ||
96 | char unit; | ||
97 | unsigned interval = 0; | ||
98 | unsigned in; | ||
99 | |||
100 | in = (desc->bEndpointAddress & USB_DIR_IN); | ||
101 | |||
102 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
103 | case USB_ENDPOINT_XFER_CONTROL: | ||
104 | if (udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | ||
105 | interval = desc->bInterval; | ||
106 | break; | ||
107 | case USB_ENDPOINT_XFER_ISOC: | ||
108 | interval = 1 << (desc->bInterval - 1); | ||
109 | break; | ||
110 | case USB_ENDPOINT_XFER_BULK: | ||
111 | if (udev->speed == USB_SPEED_HIGH && !in) /* uframes per NAK */ | ||
112 | interval = desc->bInterval; | ||
113 | break; | ||
114 | case USB_ENDPOINT_XFER_INT: | ||
115 | if (udev->speed == USB_SPEED_HIGH) | ||
116 | interval = 1 << (desc->bInterval - 1); | ||
117 | else | ||
118 | interval = desc->bInterval; | ||
119 | break; | ||
120 | } | ||
121 | interval *= (udev->speed == USB_SPEED_HIGH) ? 125 : 1000; | ||
122 | if (interval % 1000) | ||
123 | unit = 'u'; | ||
124 | else { | ||
125 | unit = 'm'; | ||
126 | interval /= 1000; | ||
127 | } | ||
128 | |||
129 | return sprintf(buf, "%d%cs\n", interval, unit); | ||
130 | } | ||
131 | static EP_ATTR(interval); | ||
132 | |||
133 | static ssize_t show_ep_direction(struct usb_device *udev, | ||
134 | struct usb_endpoint_descriptor *desc, char *buf) | ||
135 | { | ||
136 | char *direction; | ||
137 | |||
138 | if ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | ||
139 | USB_ENDPOINT_XFER_CONTROL) | ||
140 | direction = "both"; | ||
141 | else if (desc->bEndpointAddress & USB_DIR_IN) | ||
142 | direction = "in"; | ||
143 | else | ||
144 | direction = "out"; | ||
145 | return sprintf(buf, "%s\n", direction); | ||
146 | } | ||
147 | static EP_ATTR(direction); | ||
148 | |||
149 | static struct attribute *ep_attrs[] = { | ||
150 | &ep_bLength.attr, | ||
151 | &ep_bEndpointAddress.attr, | ||
152 | &ep_bmAttributes.attr, | ||
153 | &ep_bInterval.attr, | ||
154 | &ep_wMaxPacketSize.attr, | ||
155 | &ep_type.attr, | ||
156 | &ep_interval.attr, | ||
157 | &ep_direction.attr, | ||
158 | NULL, | ||
159 | }; | ||
160 | |||
161 | static void ep_object_release(struct kobject *kobj) | ||
162 | { | ||
163 | kfree(to_ep_object(kobj)); | ||
164 | } | ||
165 | |||
166 | static ssize_t ep_object_show(struct kobject *kobj, struct attribute *attr, | ||
167 | char *buf) | ||
168 | { | ||
169 | struct ep_object *ep_obj = to_ep_object(kobj); | ||
170 | struct ep_attribute *ep_attr = to_ep_attribute(attr); | ||
171 | |||
172 | return (ep_attr->show)(ep_obj->udev, ep_obj->desc, buf); | ||
173 | } | ||
174 | |||
175 | static struct sysfs_ops ep_object_sysfs_ops = { | ||
176 | .show = ep_object_show, | ||
177 | }; | ||
178 | |||
179 | static struct kobj_type ep_object_ktype = { | ||
180 | .release = ep_object_release, | ||
181 | .sysfs_ops = &ep_object_sysfs_ops, | ||
182 | .default_attrs = ep_attrs, | ||
183 | }; | ||
184 | |||
185 | static void usb_create_ep_files(struct kobject *parent, | ||
186 | struct usb_host_endpoint *endpoint, | ||
187 | struct usb_device *udev) | ||
188 | { | ||
189 | struct ep_object *ep_obj; | ||
190 | struct kobject *kobj; | ||
191 | |||
192 | ep_obj = kzalloc(sizeof(struct ep_object), GFP_KERNEL); | ||
193 | if (!ep_obj) | ||
194 | return; | ||
195 | |||
196 | ep_obj->desc = &endpoint->desc; | ||
197 | ep_obj->udev = udev; | ||
198 | |||
199 | kobj = &ep_obj->kobj; | ||
200 | kobject_set_name(kobj, "ep_%02x", endpoint->desc.bEndpointAddress); | ||
201 | kobj->parent = parent; | ||
202 | kobj->ktype = &ep_object_ktype; | ||
203 | |||
204 | /* Don't use kobject_register, because it generates a hotplug event */ | ||
205 | kobject_init(kobj); | ||
206 | if (kobject_add(kobj) == 0) | ||
207 | endpoint->kobj = kobj; | ||
208 | else | ||
209 | kobject_put(kobj); | ||
210 | } | ||
211 | |||
212 | static void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | ||
213 | { | ||
214 | |||
215 | if (endpoint->kobj) { | ||
216 | kobject_del(endpoint->kobj); | ||
217 | kobject_put(endpoint->kobj); | ||
218 | endpoint->kobj = NULL; | ||
219 | } | ||
220 | } | ||
221 | |||
25 | /* Active configuration fields */ | 222 | /* Active configuration fields */ |
26 | #define usb_actconfig_show(field, multiplier, format_string) \ | 223 | #define usb_actconfig_show(field, multiplier, format_string) \ |
27 | static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ | 224 | static ssize_t show_##field (struct device *dev, \ |
225 | struct device_attribute *attr, char *buf) \ | ||
28 | { \ | 226 | { \ |
29 | struct usb_device *udev; \ | 227 | struct usb_device *udev; \ |
30 | struct usb_host_config *actconfig; \ | 228 | struct usb_host_config *actconfig; \ |
@@ -46,22 +244,17 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") | |||
46 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") | 244 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") |
47 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") | 245 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") |
48 | 246 | ||
49 | static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf) | 247 | static ssize_t show_configuration_string(struct device *dev, |
248 | struct device_attribute *attr, char *buf) | ||
50 | { | 249 | { |
51 | struct usb_device *udev; | 250 | struct usb_device *udev; |
52 | struct usb_host_config *actconfig; | 251 | struct usb_host_config *actconfig; |
53 | int len; | ||
54 | 252 | ||
55 | udev = to_usb_device (dev); | 253 | udev = to_usb_device (dev); |
56 | actconfig = udev->actconfig; | 254 | actconfig = udev->actconfig; |
57 | if ((!actconfig) || (!actconfig->string)) | 255 | if ((!actconfig) || (!actconfig->string)) |
58 | return 0; | 256 | return 0; |
59 | len = sprintf(buf, actconfig->string, PAGE_SIZE); | 257 | return sprintf(buf, "%s\n", actconfig->string); |
60 | if (len < 0) | ||
61 | return 0; | ||
62 | buf[len] = '\n'; | ||
63 | buf[len+1] = 0; | ||
64 | return len+1; | ||
65 | } | 258 | } |
66 | static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | 259 | static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); |
67 | 260 | ||
@@ -69,7 +262,8 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | |||
69 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | 262 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); |
70 | 263 | ||
71 | static ssize_t | 264 | static ssize_t |
72 | set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 265 | set_bConfigurationValue (struct device *dev, struct device_attribute *attr, |
266 | const char *buf, size_t count) | ||
73 | { | 267 | { |
74 | struct usb_device *udev = udev = to_usb_device (dev); | 268 | struct usb_device *udev = udev = to_usb_device (dev); |
75 | int config, value; | 269 | int config, value; |
@@ -87,18 +281,13 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, | |||
87 | 281 | ||
88 | /* String fields */ | 282 | /* String fields */ |
89 | #define usb_string_attr(name) \ | 283 | #define usb_string_attr(name) \ |
90 | static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ | 284 | static ssize_t show_##name(struct device *dev, \ |
285 | struct device_attribute *attr, char *buf) \ | ||
91 | { \ | 286 | { \ |
92 | struct usb_device *udev; \ | 287 | struct usb_device *udev; \ |
93 | int len; \ | ||
94 | \ | 288 | \ |
95 | udev = to_usb_device (dev); \ | 289 | udev = to_usb_device (dev); \ |
96 | len = snprintf(buf, 256, "%s", udev->name); \ | 290 | return sprintf(buf, "%s\n", udev->name); \ |
97 | if (len < 0) \ | ||
98 | return 0; \ | ||
99 | buf[len] = '\n'; \ | ||
100 | buf[len+1] = 0; \ | ||
101 | return len+1; \ | ||
102 | } \ | 291 | } \ |
103 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); | 292 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); |
104 | 293 | ||
@@ -167,7 +356,8 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); | |||
167 | /* Descriptor fields */ | 356 | /* Descriptor fields */ |
168 | #define usb_descriptor_attr_le16(field, format_string) \ | 357 | #define usb_descriptor_attr_le16(field, format_string) \ |
169 | static ssize_t \ | 358 | static ssize_t \ |
170 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ | 359 | show_##field (struct device *dev, struct device_attribute *attr, \ |
360 | char *buf) \ | ||
171 | { \ | 361 | { \ |
172 | struct usb_device *udev; \ | 362 | struct usb_device *udev; \ |
173 | \ | 363 | \ |
@@ -183,7 +373,8 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") | |||
183 | 373 | ||
184 | #define usb_descriptor_attr(field, format_string) \ | 374 | #define usb_descriptor_attr(field, format_string) \ |
185 | static ssize_t \ | 375 | static ssize_t \ |
186 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ | 376 | show_##field (struct device *dev, struct device_attribute *attr, \ |
377 | char *buf) \ | ||
187 | { \ | 378 | { \ |
188 | struct usb_device *udev; \ | 379 | struct usb_device *udev; \ |
189 | \ | 380 | \ |
@@ -236,19 +427,21 @@ void usb_create_sysfs_dev_files (struct usb_device *udev) | |||
236 | if (udev->serial) | 427 | if (udev->serial) |
237 | device_create_file (dev, &dev_attr_serial); | 428 | device_create_file (dev, &dev_attr_serial); |
238 | device_create_file (dev, &dev_attr_configuration); | 429 | device_create_file (dev, &dev_attr_configuration); |
430 | usb_create_ep_files(&dev->kobj, &udev->ep0, udev); | ||
239 | } | 431 | } |
240 | 432 | ||
241 | void usb_remove_sysfs_dev_files (struct usb_device *udev) | 433 | void usb_remove_sysfs_dev_files (struct usb_device *udev) |
242 | { | 434 | { |
243 | struct device *dev = &udev->dev; | 435 | struct device *dev = &udev->dev; |
244 | 436 | ||
437 | usb_remove_ep_files(&udev->ep0); | ||
245 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); | 438 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); |
246 | 439 | ||
247 | if (udev->descriptor.iManufacturer) | 440 | if (udev->manufacturer) |
248 | device_remove_file(dev, &dev_attr_manufacturer); | 441 | device_remove_file(dev, &dev_attr_manufacturer); |
249 | if (udev->descriptor.iProduct) | 442 | if (udev->product) |
250 | device_remove_file(dev, &dev_attr_product); | 443 | device_remove_file(dev, &dev_attr_product); |
251 | if (udev->descriptor.iSerialNumber) | 444 | if (udev->serial) |
252 | device_remove_file(dev, &dev_attr_serial); | 445 | device_remove_file(dev, &dev_attr_serial); |
253 | device_remove_file (dev, &dev_attr_configuration); | 446 | device_remove_file (dev, &dev_attr_configuration); |
254 | } | 447 | } |
@@ -256,11 +449,13 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) | |||
256 | /* Interface fields */ | 449 | /* Interface fields */ |
257 | #define usb_intf_attr(field, format_string) \ | 450 | #define usb_intf_attr(field, format_string) \ |
258 | static ssize_t \ | 451 | static ssize_t \ |
259 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ | 452 | show_##field (struct device *dev, struct device_attribute *attr, \ |
453 | char *buf) \ | ||
260 | { \ | 454 | { \ |
261 | struct usb_interface *intf = to_usb_interface (dev); \ | 455 | struct usb_interface *intf = to_usb_interface (dev); \ |
262 | \ | 456 | \ |
263 | return sprintf (buf, format_string, intf->cur_altsetting->desc.field); \ | 457 | return sprintf (buf, format_string, \ |
458 | intf->cur_altsetting->desc.field); \ | ||
264 | } \ | 459 | } \ |
265 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 460 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
266 | 461 | ||
@@ -271,7 +466,8 @@ usb_intf_attr (bInterfaceClass, "%02x\n") | |||
271 | usb_intf_attr (bInterfaceSubClass, "%02x\n") | 466 | usb_intf_attr (bInterfaceSubClass, "%02x\n") |
272 | usb_intf_attr (bInterfaceProtocol, "%02x\n") | 467 | usb_intf_attr (bInterfaceProtocol, "%02x\n") |
273 | 468 | ||
274 | static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) | 469 | static ssize_t show_interface_string(struct device *dev, |
470 | struct device_attribute *attr, char *buf) | ||
275 | { | 471 | { |
276 | struct usb_interface *intf; | 472 | struct usb_interface *intf; |
277 | struct usb_device *udev; | 473 | struct usb_device *udev; |
@@ -288,34 +484,28 @@ static ssize_t show_interface_string(struct device *dev, struct device_attribute | |||
288 | } | 484 | } |
289 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); | 485 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); |
290 | 486 | ||
291 | static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | 487 | static ssize_t show_modalias(struct device *dev, |
488 | struct device_attribute *attr, char *buf) | ||
292 | { | 489 | { |
293 | struct usb_interface *intf; | 490 | struct usb_interface *intf; |
294 | struct usb_device *udev; | 491 | struct usb_device *udev; |
295 | int len; | 492 | struct usb_host_interface *alt; |
296 | 493 | ||
297 | intf = to_usb_interface(dev); | 494 | intf = to_usb_interface(dev); |
298 | udev = interface_to_usbdev(intf); | 495 | udev = interface_to_usbdev(intf); |
299 | 496 | alt = intf->cur_altsetting; | |
300 | len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", | 497 | |
301 | le16_to_cpu(udev->descriptor.idVendor), | 498 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" |
302 | le16_to_cpu(udev->descriptor.idProduct), | 499 | "ic%02Xisc%02Xip%02X\n", |
303 | le16_to_cpu(udev->descriptor.bcdDevice), | 500 | le16_to_cpu(udev->descriptor.idVendor), |
304 | udev->descriptor.bDeviceClass, | 501 | le16_to_cpu(udev->descriptor.idProduct), |
305 | udev->descriptor.bDeviceSubClass, | 502 | le16_to_cpu(udev->descriptor.bcdDevice), |
306 | udev->descriptor.bDeviceProtocol); | 503 | udev->descriptor.bDeviceClass, |
307 | buf += len; | 504 | udev->descriptor.bDeviceSubClass, |
308 | 505 | udev->descriptor.bDeviceProtocol, | |
309 | if (udev->descriptor.bDeviceClass == 0) { | 506 | alt->desc.bInterfaceClass, |
310 | struct usb_host_interface *alt = intf->cur_altsetting; | 507 | alt->desc.bInterfaceSubClass, |
311 | 508 | alt->desc.bInterfaceProtocol); | |
312 | return len + sprintf(buf, "%02Xisc%02Xip%02X\n", | ||
313 | alt->desc.bInterfaceClass, | ||
314 | alt->desc.bInterfaceSubClass, | ||
315 | alt->desc.bInterfaceProtocol); | ||
316 | } else { | ||
317 | return len + sprintf(buf, "*isc*ip*\n"); | ||
318 | } | ||
319 | } | 509 | } |
320 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 510 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); |
321 | 511 | ||
@@ -333,20 +523,47 @@ static struct attribute_group intf_attr_grp = { | |||
333 | .attrs = intf_attrs, | 523 | .attrs = intf_attrs, |
334 | }; | 524 | }; |
335 | 525 | ||
526 | static inline void usb_create_intf_ep_files(struct usb_interface *intf, | ||
527 | struct usb_device *udev) | ||
528 | { | ||
529 | struct usb_host_interface *iface_desc; | ||
530 | int i; | ||
531 | |||
532 | iface_desc = intf->cur_altsetting; | ||
533 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) | ||
534 | usb_create_ep_files(&intf->dev.kobj, &iface_desc->endpoint[i], | ||
535 | udev); | ||
536 | } | ||
537 | |||
538 | static inline void usb_remove_intf_ep_files(struct usb_interface *intf) | ||
539 | { | ||
540 | struct usb_host_interface *iface_desc; | ||
541 | int i; | ||
542 | |||
543 | iface_desc = intf->cur_altsetting; | ||
544 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) | ||
545 | usb_remove_ep_files(&iface_desc->endpoint[i]); | ||
546 | } | ||
547 | |||
336 | void usb_create_sysfs_intf_files (struct usb_interface *intf) | 548 | void usb_create_sysfs_intf_files (struct usb_interface *intf) |
337 | { | 549 | { |
550 | struct usb_device *udev = interface_to_usbdev(intf); | ||
551 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
552 | |||
338 | sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); | 553 | sysfs_create_group(&intf->dev.kobj, &intf_attr_grp); |
339 | 554 | ||
340 | if (intf->cur_altsetting->string) | 555 | if (alt->string == NULL) |
556 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | ||
557 | if (alt->string) | ||
341 | device_create_file(&intf->dev, &dev_attr_interface); | 558 | device_create_file(&intf->dev, &dev_attr_interface); |
342 | 559 | usb_create_intf_ep_files(intf, udev); | |
343 | } | 560 | } |
344 | 561 | ||
345 | void usb_remove_sysfs_intf_files (struct usb_interface *intf) | 562 | void usb_remove_sysfs_intf_files (struct usb_interface *intf) |
346 | { | 563 | { |
564 | usb_remove_intf_ep_files(intf); | ||
347 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); | 565 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); |
348 | 566 | ||
349 | if (intf->cur_altsetting->string) | 567 | if (intf->cur_altsetting->string) |
350 | device_remove_file(&intf->dev, &dev_attr_interface); | 568 | device_remove_file(&intf->dev, &dev_attr_interface); |
351 | |||
352 | } | 569 | } |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index b32898e0a27d..f2a1fed2a802 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -237,7 +237,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
237 | (dev->state < USB_STATE_DEFAULT) || | 237 | (dev->state < USB_STATE_DEFAULT) || |
238 | (!dev->bus) || (dev->devnum <= 0)) | 238 | (!dev->bus) || (dev->devnum <= 0)) |
239 | return -ENODEV; | 239 | return -ENODEV; |
240 | if (dev->state == USB_STATE_SUSPENDED) | 240 | if (dev->bus->controller->power.power_state.event != PM_EVENT_ON |
241 | || dev->state == USB_STATE_SUSPENDED) | ||
241 | return -EHOSTUNREACH; | 242 | return -EHOSTUNREACH; |
242 | if (!(op = dev->bus->op) || !op->submit_urb) | 243 | if (!(op = dev->bus->op) || !op->submit_urb) |
243 | return -ENODEV; | 244 | return -ENODEV; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4c57f3f649ed..0eefff7bcb3c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -107,10 +107,19 @@ static int usb_probe_interface(struct device *dev) | |||
107 | id = usb_match_id (intf, driver->id_table); | 107 | id = usb_match_id (intf, driver->id_table); |
108 | if (id) { | 108 | if (id) { |
109 | dev_dbg (dev, "%s - got id\n", __FUNCTION__); | 109 | dev_dbg (dev, "%s - got id\n", __FUNCTION__); |
110 | |||
111 | /* Interface "power state" doesn't correspond to any hardware | ||
112 | * state whatsoever. We use it to record when it's bound to | ||
113 | * a driver that may start I/0: it's not frozen/quiesced. | ||
114 | */ | ||
115 | mark_active(intf); | ||
110 | intf->condition = USB_INTERFACE_BINDING; | 116 | intf->condition = USB_INTERFACE_BINDING; |
111 | error = driver->probe (intf, id); | 117 | error = driver->probe (intf, id); |
112 | intf->condition = error ? USB_INTERFACE_UNBOUND : | 118 | if (error) { |
113 | USB_INTERFACE_BOUND; | 119 | mark_quiesced(intf); |
120 | intf->condition = USB_INTERFACE_UNBOUND; | ||
121 | } else | ||
122 | intf->condition = USB_INTERFACE_BOUND; | ||
114 | } | 123 | } |
115 | 124 | ||
116 | return error; | 125 | return error; |
@@ -136,6 +145,7 @@ static int usb_unbind_interface(struct device *dev) | |||
136 | 0); | 145 | 0); |
137 | usb_set_intfdata(intf, NULL); | 146 | usb_set_intfdata(intf, NULL); |
138 | intf->condition = USB_INTERFACE_UNBOUND; | 147 | intf->condition = USB_INTERFACE_UNBOUND; |
148 | mark_quiesced(intf); | ||
139 | 149 | ||
140 | return 0; | 150 | return 0; |
141 | } | 151 | } |
@@ -299,6 +309,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
299 | dev->driver = &driver->driver; | 309 | dev->driver = &driver->driver; |
300 | usb_set_intfdata(iface, priv); | 310 | usb_set_intfdata(iface, priv); |
301 | iface->condition = USB_INTERFACE_BOUND; | 311 | iface->condition = USB_INTERFACE_BOUND; |
312 | mark_active(iface); | ||
302 | 313 | ||
303 | /* if interface was already added, bind now; else let | 314 | /* if interface was already added, bind now; else let |
304 | * the future device_add() bind it, bypassing probe() | 315 | * the future device_add() bind it, bypassing probe() |
@@ -345,6 +356,7 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
345 | dev->driver = NULL; | 356 | dev->driver = NULL; |
346 | usb_set_intfdata(iface, NULL); | 357 | usb_set_intfdata(iface, NULL); |
347 | iface->condition = USB_INTERFACE_UNBOUND; | 358 | iface->condition = USB_INTERFACE_UNBOUND; |
359 | mark_quiesced(iface); | ||
348 | } | 360 | } |
349 | 361 | ||
350 | /** | 362 | /** |
@@ -557,6 +569,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
557 | { | 569 | { |
558 | struct usb_interface *intf; | 570 | struct usb_interface *intf; |
559 | struct usb_device *usb_dev; | 571 | struct usb_device *usb_dev; |
572 | struct usb_host_interface *alt; | ||
560 | int i = 0; | 573 | int i = 0; |
561 | int length = 0; | 574 | int length = 0; |
562 | 575 | ||
@@ -573,7 +586,8 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
573 | 586 | ||
574 | intf = to_usb_interface(dev); | 587 | intf = to_usb_interface(dev); |
575 | usb_dev = interface_to_usbdev (intf); | 588 | usb_dev = interface_to_usbdev (intf); |
576 | 589 | alt = intf->cur_altsetting; | |
590 | |||
577 | if (usb_dev->devnum < 0) { | 591 | if (usb_dev->devnum < 0) { |
578 | pr_debug ("usb %s: already deleted?\n", dev->bus_id); | 592 | pr_debug ("usb %s: already deleted?\n", dev->bus_id); |
579 | return -ENODEV; | 593 | return -ENODEV; |
@@ -615,46 +629,27 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp, | |||
615 | usb_dev->descriptor.bDeviceProtocol)) | 629 | usb_dev->descriptor.bDeviceProtocol)) |
616 | return -ENOMEM; | 630 | return -ENOMEM; |
617 | 631 | ||
618 | if (usb_dev->descriptor.bDeviceClass == 0) { | 632 | if (add_hotplug_env_var(envp, num_envp, &i, |
619 | struct usb_host_interface *alt = intf->cur_altsetting; | 633 | buffer, buffer_size, &length, |
634 | "INTERFACE=%d/%d/%d", | ||
635 | alt->desc.bInterfaceClass, | ||
636 | alt->desc.bInterfaceSubClass, | ||
637 | alt->desc.bInterfaceProtocol)) | ||
638 | return -ENOMEM; | ||
620 | 639 | ||
621 | /* 2.4 only exposed interface zero. in 2.5, hotplug | 640 | if (add_hotplug_env_var(envp, num_envp, &i, |
622 | * agents are called for all interfaces, and can use | 641 | buffer, buffer_size, &length, |
623 | * $DEVPATH/bInterfaceNumber if necessary. | 642 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", |
624 | */ | 643 | le16_to_cpu(usb_dev->descriptor.idVendor), |
625 | if (add_hotplug_env_var(envp, num_envp, &i, | 644 | le16_to_cpu(usb_dev->descriptor.idProduct), |
626 | buffer, buffer_size, &length, | 645 | le16_to_cpu(usb_dev->descriptor.bcdDevice), |
627 | "INTERFACE=%d/%d/%d", | 646 | usb_dev->descriptor.bDeviceClass, |
628 | alt->desc.bInterfaceClass, | 647 | usb_dev->descriptor.bDeviceSubClass, |
629 | alt->desc.bInterfaceSubClass, | 648 | usb_dev->descriptor.bDeviceProtocol, |
630 | alt->desc.bInterfaceProtocol)) | 649 | alt->desc.bInterfaceClass, |
631 | return -ENOMEM; | 650 | alt->desc.bInterfaceSubClass, |
632 | 651 | alt->desc.bInterfaceProtocol)) | |
633 | if (add_hotplug_env_var(envp, num_envp, &i, | 652 | return -ENOMEM; |
634 | buffer, buffer_size, &length, | ||
635 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | ||
636 | le16_to_cpu(usb_dev->descriptor.idVendor), | ||
637 | le16_to_cpu(usb_dev->descriptor.idProduct), | ||
638 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | ||
639 | usb_dev->descriptor.bDeviceClass, | ||
640 | usb_dev->descriptor.bDeviceSubClass, | ||
641 | usb_dev->descriptor.bDeviceProtocol, | ||
642 | alt->desc.bInterfaceClass, | ||
643 | alt->desc.bInterfaceSubClass, | ||
644 | alt->desc.bInterfaceProtocol)) | ||
645 | return -ENOMEM; | ||
646 | } else { | ||
647 | if (add_hotplug_env_var(envp, num_envp, &i, | ||
648 | buffer, buffer_size, &length, | ||
649 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*", | ||
650 | le16_to_cpu(usb_dev->descriptor.idVendor), | ||
651 | le16_to_cpu(usb_dev->descriptor.idProduct), | ||
652 | le16_to_cpu(usb_dev->descriptor.bcdDevice), | ||
653 | usb_dev->descriptor.bDeviceClass, | ||
654 | usb_dev->descriptor.bDeviceSubClass, | ||
655 | usb_dev->descriptor.bDeviceProtocol)) | ||
656 | return -ENOMEM; | ||
657 | } | ||
658 | 653 | ||
659 | envp[i] = NULL; | 654 | envp[i] = NULL; |
660 | 655 | ||
@@ -709,12 +704,10 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
709 | { | 704 | { |
710 | struct usb_device *dev; | 705 | struct usb_device *dev; |
711 | 706 | ||
712 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 707 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
713 | if (!dev) | 708 | if (!dev) |
714 | return NULL; | 709 | return NULL; |
715 | 710 | ||
716 | memset(dev, 0, sizeof(*dev)); | ||
717 | |||
718 | bus = usb_bus_get(bus); | 711 | bus = usb_bus_get(bus); |
719 | if (!bus) { | 712 | if (!bus) { |
720 | kfree(dev); | 713 | kfree(dev); |
@@ -1402,13 +1395,30 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, | |||
1402 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 1395 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
1403 | } | 1396 | } |
1404 | 1397 | ||
1398 | static int verify_suspended(struct device *dev, void *unused) | ||
1399 | { | ||
1400 | return (dev->power.power_state.event == PM_EVENT_ON) ? -EBUSY : 0; | ||
1401 | } | ||
1402 | |||
1405 | static int usb_generic_suspend(struct device *dev, pm_message_t message) | 1403 | static int usb_generic_suspend(struct device *dev, pm_message_t message) |
1406 | { | 1404 | { |
1407 | struct usb_interface *intf; | 1405 | struct usb_interface *intf; |
1408 | struct usb_driver *driver; | 1406 | struct usb_driver *driver; |
1407 | int status; | ||
1409 | 1408 | ||
1410 | if (dev->driver == &usb_generic_driver) | 1409 | /* USB devices enter SUSPEND state through their hubs, but can be |
1411 | return usb_suspend_device (to_usb_device(dev), message); | 1410 | * marked for FREEZE as soon as their children are already idled. |
1411 | * But those semantics are useless, so we equate the two (sigh). | ||
1412 | */ | ||
1413 | if (dev->driver == &usb_generic_driver) { | ||
1414 | if (dev->power.power_state.event == message.event) | ||
1415 | return 0; | ||
1416 | /* we need to rule out bogus requests through sysfs */ | ||
1417 | status = device_for_each_child(dev, NULL, verify_suspended); | ||
1418 | if (status) | ||
1419 | return status; | ||
1420 | return usb_suspend_device (to_usb_device(dev)); | ||
1421 | } | ||
1412 | 1422 | ||
1413 | if ((dev->driver == NULL) || | 1423 | if ((dev->driver == NULL) || |
1414 | (dev->driver_data == &usb_generic_driver_data)) | 1424 | (dev->driver_data == &usb_generic_driver_data)) |
@@ -1417,23 +1427,44 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message) | |||
1417 | intf = to_usb_interface(dev); | 1427 | intf = to_usb_interface(dev); |
1418 | driver = to_usb_driver(dev->driver); | 1428 | driver = to_usb_driver(dev->driver); |
1419 | 1429 | ||
1420 | /* there's only one USB suspend state */ | 1430 | /* with no hardware, USB interfaces only use FREEZE and ON states */ |
1421 | if (intf->dev.power.power_state.event) | 1431 | if (!is_active(intf)) |
1422 | return 0; | 1432 | return 0; |
1423 | 1433 | ||
1424 | if (driver->suspend) | 1434 | if (driver->suspend && driver->resume) { |
1425 | return driver->suspend(intf, message); | 1435 | status = driver->suspend(intf, message); |
1426 | return 0; | 1436 | if (status) |
1437 | dev_err(dev, "%s error %d\n", "suspend", status); | ||
1438 | else | ||
1439 | mark_quiesced(intf); | ||
1440 | } else { | ||
1441 | // FIXME else if there's no suspend method, disconnect... | ||
1442 | dev_warn(dev, "no %s?\n", "suspend"); | ||
1443 | status = 0; | ||
1444 | } | ||
1445 | return status; | ||
1427 | } | 1446 | } |
1428 | 1447 | ||
1429 | static int usb_generic_resume(struct device *dev) | 1448 | static int usb_generic_resume(struct device *dev) |
1430 | { | 1449 | { |
1431 | struct usb_interface *intf; | 1450 | struct usb_interface *intf; |
1432 | struct usb_driver *driver; | 1451 | struct usb_driver *driver; |
1452 | struct usb_device *udev; | ||
1453 | int status; | ||
1433 | 1454 | ||
1434 | /* devices resume through their hub */ | 1455 | if (dev->power.power_state.event == PM_EVENT_ON) |
1435 | if (dev->driver == &usb_generic_driver) | 1456 | return 0; |
1457 | |||
1458 | /* mark things as "on" immediately, no matter what errors crop up */ | ||
1459 | dev->power.power_state.event = PM_EVENT_ON; | ||
1460 | |||
1461 | /* devices resume through their hubs */ | ||
1462 | if (dev->driver == &usb_generic_driver) { | ||
1463 | udev = to_usb_device(dev); | ||
1464 | if (udev->state == USB_STATE_NOTATTACHED) | ||
1465 | return 0; | ||
1436 | return usb_resume_device (to_usb_device(dev)); | 1466 | return usb_resume_device (to_usb_device(dev)); |
1467 | } | ||
1437 | 1468 | ||
1438 | if ((dev->driver == NULL) || | 1469 | if ((dev->driver == NULL) || |
1439 | (dev->driver_data == &usb_generic_driver_data)) | 1470 | (dev->driver_data == &usb_generic_driver_data)) |
@@ -1442,8 +1473,22 @@ static int usb_generic_resume(struct device *dev) | |||
1442 | intf = to_usb_interface(dev); | 1473 | intf = to_usb_interface(dev); |
1443 | driver = to_usb_driver(dev->driver); | 1474 | driver = to_usb_driver(dev->driver); |
1444 | 1475 | ||
1445 | if (driver->resume) | 1476 | udev = interface_to_usbdev(intf); |
1446 | return driver->resume(intf); | 1477 | if (udev->state == USB_STATE_NOTATTACHED) |
1478 | return 0; | ||
1479 | |||
1480 | /* if driver was suspended, it has a resume method; | ||
1481 | * however, sysfs can wrongly mark things as suspended | ||
1482 | * (on the "no suspend method" FIXME path above) | ||
1483 | */ | ||
1484 | if (driver->resume) { | ||
1485 | status = driver->resume(intf); | ||
1486 | if (status) { | ||
1487 | dev_err(dev, "%s error %d\n", "resume", status); | ||
1488 | mark_quiesced(intf); | ||
1489 | } | ||
1490 | } else | ||
1491 | dev_warn(dev, "no %s?\n", "resume"); | ||
1447 | return 0; | 1492 | return 0; |
1448 | } | 1493 | } |
1449 | 1494 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index e6504f3370ad..1c4a68499dce 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -13,12 +13,14 @@ extern void usb_disable_device (struct usb_device *dev, int skip_ep0); | |||
13 | 13 | ||
14 | extern int usb_get_device_descriptor(struct usb_device *dev, | 14 | extern int usb_get_device_descriptor(struct usb_device *dev, |
15 | unsigned int size); | 15 | unsigned int size); |
16 | extern char *usb_cache_string(struct usb_device *udev, int index); | ||
16 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
17 | 18 | ||
18 | extern void usb_lock_all_devices(void); | 19 | extern void usb_lock_all_devices(void); |
19 | extern void usb_unlock_all_devices(void); | 20 | extern void usb_unlock_all_devices(void); |
20 | 21 | ||
21 | extern void usb_kick_khubd(struct usb_device *dev); | 22 | extern void usb_kick_khubd(struct usb_device *dev); |
23 | extern void usb_suspend_root_hub(struct usb_device *hdev); | ||
22 | extern void usb_resume_root_hub(struct usb_device *dev); | 24 | extern void usb_resume_root_hub(struct usb_device *dev); |
23 | 25 | ||
24 | extern int usb_hub_init(void); | 26 | extern int usb_hub_init(void); |
@@ -28,6 +30,28 @@ extern void usb_major_cleanup(void); | |||
28 | extern int usb_host_init(void); | 30 | extern int usb_host_init(void); |
29 | extern void usb_host_cleanup(void); | 31 | extern void usb_host_cleanup(void); |
30 | 32 | ||
33 | extern int usb_suspend_device(struct usb_device *dev); | ||
34 | extern int usb_resume_device(struct usb_device *dev); | ||
35 | |||
36 | |||
37 | /* Interfaces and their "power state" are owned by usbcore */ | ||
38 | |||
39 | static inline void mark_active(struct usb_interface *f) | ||
40 | { | ||
41 | f->dev.power.power_state.event = PM_EVENT_ON; | ||
42 | } | ||
43 | |||
44 | static inline void mark_quiesced(struct usb_interface *f) | ||
45 | { | ||
46 | f->dev.power.power_state.event = PM_EVENT_FREEZE; | ||
47 | } | ||
48 | |||
49 | static inline int is_active(struct usb_interface *f) | ||
50 | { | ||
51 | return f->dev.power.power_state.event == PM_EVENT_ON; | ||
52 | } | ||
53 | |||
54 | |||
31 | /* for labeling diagnostics */ | 55 | /* for labeling diagnostics */ |
32 | extern const char *usbcore_name; | 56 | extern const char *usbcore_name; |
33 | 57 | ||
@@ -39,9 +63,6 @@ extern void usbfs_conn_disc_event(void); | |||
39 | 63 | ||
40 | extern int usbdev_init(void); | 64 | extern int usbdev_init(void); |
41 | extern void usbdev_cleanup(void); | 65 | extern void usbdev_cleanup(void); |
42 | extern void usbdev_add(struct usb_device *dev); | ||
43 | extern void usbdev_remove(struct usb_device *dev); | ||
44 | extern struct usb_device *usbdev_lookup_minor(int minor); | ||
45 | 66 | ||
46 | struct dev_state { | 67 | struct dev_state { |
47 | struct list_head list; /* state list */ | 68 | struct list_head list; /* state list */ |
@@ -58,3 +79,9 @@ struct dev_state { | |||
58 | unsigned long ifclaimed; | 79 | unsigned long ifclaimed; |
59 | }; | 80 | }; |
60 | 81 | ||
82 | /* internal notify stuff */ | ||
83 | extern void usb_notify_add_device(struct usb_device *udev); | ||
84 | extern void usb_notify_remove_device(struct usb_device *udev); | ||
85 | extern void usb_notify_add_bus(struct usb_bus *ubus); | ||
86 | extern void usb_notify_remove_bus(struct usb_bus *ubus); | ||
87 | |||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 503201764f6b..02106bebd5c1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -967,6 +967,7 @@ static int dummy_udc_resume (struct device *dev) | |||
967 | 967 | ||
968 | static struct device_driver dummy_udc_driver = { | 968 | static struct device_driver dummy_udc_driver = { |
969 | .name = (char *) gadget_name, | 969 | .name = (char *) gadget_name, |
970 | .owner = THIS_MODULE, | ||
970 | .bus = &platform_bus_type, | 971 | .bus = &platform_bus_type, |
971 | .probe = dummy_udc_probe, | 972 | .probe = dummy_udc_probe, |
972 | .remove = dummy_udc_remove, | 973 | .remove = dummy_udc_remove, |
@@ -1751,7 +1752,7 @@ static int dummy_hub_control ( | |||
1751 | return retval; | 1752 | return retval; |
1752 | } | 1753 | } |
1753 | 1754 | ||
1754 | static int dummy_hub_suspend (struct usb_hcd *hcd) | 1755 | static int dummy_bus_suspend (struct usb_hcd *hcd) |
1755 | { | 1756 | { |
1756 | struct dummy *dum = hcd_to_dummy (hcd); | 1757 | struct dummy *dum = hcd_to_dummy (hcd); |
1757 | 1758 | ||
@@ -1762,7 +1763,7 @@ static int dummy_hub_suspend (struct usb_hcd *hcd) | |||
1762 | return 0; | 1763 | return 0; |
1763 | } | 1764 | } |
1764 | 1765 | ||
1765 | static int dummy_hub_resume (struct usb_hcd *hcd) | 1766 | static int dummy_bus_resume (struct usb_hcd *hcd) |
1766 | { | 1767 | { |
1767 | struct dummy *dum = hcd_to_dummy (hcd); | 1768 | struct dummy *dum = hcd_to_dummy (hcd); |
1768 | 1769 | ||
@@ -1894,8 +1895,8 @@ static const struct hc_driver dummy_hcd = { | |||
1894 | 1895 | ||
1895 | .hub_status_data = dummy_hub_status, | 1896 | .hub_status_data = dummy_hub_status, |
1896 | .hub_control = dummy_hub_control, | 1897 | .hub_control = dummy_hub_control, |
1897 | .hub_suspend = dummy_hub_suspend, | 1898 | .bus_suspend = dummy_bus_suspend, |
1898 | .hub_resume = dummy_hub_resume, | 1899 | .bus_resume = dummy_bus_resume, |
1899 | }; | 1900 | }; |
1900 | 1901 | ||
1901 | static int dummy_hcd_probe (struct device *dev) | 1902 | static int dummy_hcd_probe (struct device *dev) |
@@ -1936,13 +1937,6 @@ static int dummy_hcd_suspend (struct device *dev, pm_message_t state) | |||
1936 | dev_dbg (dev, "%s\n", __FUNCTION__); | 1937 | dev_dbg (dev, "%s\n", __FUNCTION__); |
1937 | hcd = dev_get_drvdata (dev); | 1938 | hcd = dev_get_drvdata (dev); |
1938 | 1939 | ||
1939 | #ifndef CONFIG_USB_SUSPEND | ||
1940 | /* Otherwise this would never happen */ | ||
1941 | usb_lock_device (hcd->self.root_hub); | ||
1942 | dummy_hub_suspend (hcd); | ||
1943 | usb_unlock_device (hcd->self.root_hub); | ||
1944 | #endif | ||
1945 | |||
1946 | hcd->state = HC_STATE_SUSPENDED; | 1940 | hcd->state = HC_STATE_SUSPENDED; |
1947 | return 0; | 1941 | return 0; |
1948 | } | 1942 | } |
@@ -1955,19 +1949,13 @@ static int dummy_hcd_resume (struct device *dev) | |||
1955 | hcd = dev_get_drvdata (dev); | 1949 | hcd = dev_get_drvdata (dev); |
1956 | hcd->state = HC_STATE_RUNNING; | 1950 | hcd->state = HC_STATE_RUNNING; |
1957 | 1951 | ||
1958 | #ifndef CONFIG_USB_SUSPEND | ||
1959 | /* Otherwise this would never happen */ | ||
1960 | usb_lock_device (hcd->self.root_hub); | ||
1961 | dummy_hub_resume (hcd); | ||
1962 | usb_unlock_device (hcd->self.root_hub); | ||
1963 | #endif | ||
1964 | |||
1965 | usb_hcd_poll_rh_status (hcd); | 1952 | usb_hcd_poll_rh_status (hcd); |
1966 | return 0; | 1953 | return 0; |
1967 | } | 1954 | } |
1968 | 1955 | ||
1969 | static struct device_driver dummy_hcd_driver = { | 1956 | static struct device_driver dummy_hcd_driver = { |
1970 | .name = (char *) driver_name, | 1957 | .name = (char *) driver_name, |
1958 | .owner = THIS_MODULE, | ||
1971 | .bus = &platform_bus_type, | 1959 | .bus = &platform_bus_type, |
1972 | .probe = dummy_hcd_probe, | 1960 | .probe = dummy_hcd_probe, |
1973 | .remove = dummy_hcd_remove, | 1961 | .remove = dummy_hcd_remove, |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index f1024e804d5c..8f402f85e1ca 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -2533,6 +2533,7 @@ static struct usb_gadget_driver eth_driver = { | |||
2533 | 2533 | ||
2534 | .driver = { | 2534 | .driver = { |
2535 | .name = (char *) shortname, | 2535 | .name = (char *) shortname, |
2536 | .owner = THIS_MODULE, | ||
2536 | // .shutdown = ... | 2537 | // .shutdown = ... |
2537 | // .suspend = ... | 2538 | // .suspend = ... |
2538 | // .resume = ... | 2539 | // .resume = ... |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a41d9d4baee3..ea09aaa3cab6 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kthread.h> | ||
227 | #include <linux/limits.h> | 228 | #include <linux/limits.h> |
228 | #include <linux/list.h> | 229 | #include <linux/list.h> |
229 | #include <linux/module.h> | 230 | #include <linux/module.h> |
@@ -669,7 +670,6 @@ struct fsg_dev { | |||
669 | wait_queue_head_t thread_wqh; | 670 | wait_queue_head_t thread_wqh; |
670 | int thread_wakeup_needed; | 671 | int thread_wakeup_needed; |
671 | struct completion thread_notifier; | 672 | struct completion thread_notifier; |
672 | int thread_pid; | ||
673 | struct task_struct *thread_task; | 673 | struct task_struct *thread_task; |
674 | sigset_t thread_signal_mask; | 674 | sigset_t thread_signal_mask; |
675 | 675 | ||
@@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev *fsg) | |||
1084 | static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | 1084 | static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) |
1085 | { | 1085 | { |
1086 | unsigned long flags; | 1086 | unsigned long flags; |
1087 | struct task_struct *thread_task; | ||
1088 | 1087 | ||
1089 | /* Do nothing if a higher-priority exception is already in progress. | 1088 | /* Do nothing if a higher-priority exception is already in progress. |
1090 | * If a lower-or-equal priority exception is in progress, preempt it | 1089 | * If a lower-or-equal priority exception is in progress, preempt it |
@@ -1093,9 +1092,9 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | |||
1093 | if (fsg->state <= new_state) { | 1092 | if (fsg->state <= new_state) { |
1094 | fsg->exception_req_tag = fsg->ep0_req_tag; | 1093 | fsg->exception_req_tag = fsg->ep0_req_tag; |
1095 | fsg->state = new_state; | 1094 | fsg->state = new_state; |
1096 | thread_task = fsg->thread_task; | 1095 | if (fsg->thread_task) |
1097 | if (thread_task) | 1096 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, |
1098 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task); | 1097 | fsg->thread_task); |
1099 | } | 1098 | } |
1100 | spin_unlock_irqrestore(&fsg->lock, flags); | 1099 | spin_unlock_irqrestore(&fsg->lock, flags); |
1101 | } | 1100 | } |
@@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_) | |||
3383 | { | 3382 | { |
3384 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; | 3383 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; |
3385 | 3384 | ||
3386 | fsg->thread_task = current; | ||
3387 | |||
3388 | /* Release all our userspace resources */ | ||
3389 | daemonize("file-storage-gadget"); | ||
3390 | |||
3391 | /* Allow the thread to be killed by a signal, but set the signal mask | 3385 | /* Allow the thread to be killed by a signal, but set the signal mask |
3392 | * to block everything but INT, TERM, KILL, and USR1. */ | 3386 | * to block everything but INT, TERM, KILL, and USR1. */ |
3393 | siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | | 3387 | siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | |
@@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_) | |||
3400 | * that expects a __user pointer and it will work okay. */ | 3394 | * that expects a __user pointer and it will work okay. */ |
3401 | set_fs(get_ds()); | 3395 | set_fs(get_ds()); |
3402 | 3396 | ||
3403 | /* Wait for the gadget registration to finish up */ | ||
3404 | wait_for_completion(&fsg->thread_notifier); | ||
3405 | |||
3406 | /* The main loop */ | 3397 | /* The main loop */ |
3407 | while (fsg->state != FSG_STATE_TERMINATED) { | 3398 | while (fsg->state != FSG_STATE_TERMINATED) { |
3408 | if (exception_in_progress(fsg) || signal_pending(current)) { | 3399 | if (exception_in_progress(fsg) || signal_pending(current)) { |
@@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_) | |||
3440 | spin_unlock_irq(&fsg->lock); | 3431 | spin_unlock_irq(&fsg->lock); |
3441 | } | 3432 | } |
3442 | 3433 | ||
3434 | spin_lock_irq(&fsg->lock); | ||
3443 | fsg->thread_task = NULL; | 3435 | fsg->thread_task = NULL; |
3444 | flush_signals(current); | 3436 | spin_unlock_irq(&fsg->lock); |
3445 | 3437 | ||
3446 | /* In case we are exiting because of a signal, unregister the | 3438 | /* In case we are exiting because of a signal, unregister the |
3447 | * gadget driver and close the backing file. */ | 3439 | * gadget driver and close the backing file. */ |
@@ -3831,12 +3823,11 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3831 | 3823 | ||
3832 | /* Create the LUNs, open their backing files, and register the | 3824 | /* Create the LUNs, open their backing files, and register the |
3833 | * LUN devices in sysfs. */ | 3825 | * LUN devices in sysfs. */ |
3834 | fsg->luns = kmalloc(i * sizeof(struct lun), GFP_KERNEL); | 3826 | fsg->luns = kzalloc(i * sizeof(struct lun), GFP_KERNEL); |
3835 | if (!fsg->luns) { | 3827 | if (!fsg->luns) { |
3836 | rc = -ENOMEM; | 3828 | rc = -ENOMEM; |
3837 | goto out; | 3829 | goto out; |
3838 | } | 3830 | } |
3839 | memset(fsg->luns, 0, i * sizeof(struct lun)); | ||
3840 | fsg->nluns = i; | 3831 | fsg->nluns = i; |
3841 | 3832 | ||
3842 | for (i = 0; i < fsg->nluns; ++i) { | 3833 | for (i = 0; i < fsg->nluns; ++i) { |
@@ -3959,10 +3950,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3959 | sprintf(&serial[i], "%02X", c); | 3950 | sprintf(&serial[i], "%02X", c); |
3960 | } | 3951 | } |
3961 | 3952 | ||
3962 | if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS | | 3953 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, |
3963 | CLONE_FILES))) < 0) | 3954 | "file-storage-gadget"); |
3955 | if (IS_ERR(fsg->thread_task)) { | ||
3956 | rc = PTR_ERR(fsg->thread_task); | ||
3964 | goto out; | 3957 | goto out; |
3965 | fsg->thread_pid = rc; | 3958 | } |
3966 | 3959 | ||
3967 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | 3960 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); |
3968 | INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); | 3961 | INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); |
@@ -3994,7 +3987,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3994 | DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", | 3987 | DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", |
3995 | mod_data.removable, mod_data.can_stall, | 3988 | mod_data.removable, mod_data.can_stall, |
3996 | mod_data.buflen); | 3989 | mod_data.buflen); |
3997 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid); | 3990 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); |
3991 | |||
3992 | set_bit(REGISTERED, &fsg->atomic_bitflags); | ||
3993 | |||
3994 | /* Tell the thread to start working */ | ||
3995 | wake_up_process(fsg->thread_task); | ||
3998 | return 0; | 3996 | return 0; |
3999 | 3997 | ||
4000 | autoconf_fail: | 3998 | autoconf_fail: |
@@ -4046,6 +4044,7 @@ static struct usb_gadget_driver fsg_driver = { | |||
4046 | 4044 | ||
4047 | .driver = { | 4045 | .driver = { |
4048 | .name = (char *) shortname, | 4046 | .name = (char *) shortname, |
4047 | .owner = THIS_MODULE, | ||
4049 | // .release = ... | 4048 | // .release = ... |
4050 | // .suspend = ... | 4049 | // .suspend = ... |
4051 | // .resume = ... | 4050 | // .resume = ... |
@@ -4057,10 +4056,9 @@ static int __init fsg_alloc(void) | |||
4057 | { | 4056 | { |
4058 | struct fsg_dev *fsg; | 4057 | struct fsg_dev *fsg; |
4059 | 4058 | ||
4060 | fsg = kmalloc(sizeof *fsg, GFP_KERNEL); | 4059 | fsg = kzalloc(sizeof *fsg, GFP_KERNEL); |
4061 | if (!fsg) | 4060 | if (!fsg) |
4062 | return -ENOMEM; | 4061 | return -ENOMEM; |
4063 | memset(fsg, 0, sizeof *fsg); | ||
4064 | spin_lock_init(&fsg->lock); | 4062 | spin_lock_init(&fsg->lock); |
4065 | init_rwsem(&fsg->filesem); | 4063 | init_rwsem(&fsg->filesem); |
4066 | init_waitqueue_head(&fsg->thread_wqh); | 4064 | init_waitqueue_head(&fsg->thread_wqh); |
@@ -4086,15 +4084,9 @@ static int __init fsg_init(void) | |||
4086 | if ((rc = fsg_alloc()) != 0) | 4084 | if ((rc = fsg_alloc()) != 0) |
4087 | return rc; | 4085 | return rc; |
4088 | fsg = the_fsg; | 4086 | fsg = the_fsg; |
4089 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) { | 4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4090 | fsg_free(fsg); | 4088 | fsg_free(fsg); |
4091 | return rc; | 4089 | return rc; |
4092 | } | ||
4093 | set_bit(REGISTERED, &fsg->atomic_bitflags); | ||
4094 | |||
4095 | /* Tell the thread to start working */ | ||
4096 | complete(&fsg->thread_notifier); | ||
4097 | return 0; | ||
4098 | } | 4090 | } |
4099 | module_init(fsg_init); | 4091 | module_init(fsg_init); |
4100 | 4092 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index b0f3cd63e3b9..654469778ab5 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1970,6 +1970,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); | |||
1970 | static struct pci_driver goku_pci_driver = { | 1970 | static struct pci_driver goku_pci_driver = { |
1971 | .name = (char *) driver_name, | 1971 | .name = (char *) driver_name, |
1972 | .id_table = pci_ids, | 1972 | .id_table = pci_ids, |
1973 | .owner = THIS_MODULE, | ||
1973 | 1974 | ||
1974 | .probe = goku_probe, | 1975 | .probe = goku_probe, |
1975 | .remove = goku_remove, | 1976 | .remove = goku_remove, |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 012d1e5f1524..9b3673904daf 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -2140,6 +2140,7 @@ static int lh7a40x_udc_remove(struct device *_dev) | |||
2140 | 2140 | ||
2141 | static struct device_driver udc_driver = { | 2141 | static struct device_driver udc_driver = { |
2142 | .name = (char *)driver_name, | 2142 | .name = (char *)driver_name, |
2143 | .owner = THIS_MODULE, | ||
2143 | .bus = &platform_bus_type, | 2144 | .bus = &platform_bus_type, |
2144 | .probe = lh7a40x_udc_probe, | 2145 | .probe = lh7a40x_udc_probe, |
2145 | .remove = lh7a40x_udc_remove | 2146 | .remove = lh7a40x_udc_remove |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c32e1f7476da..0dc6bb00bf72 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -2948,6 +2948,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); | |||
2948 | static struct pci_driver net2280_pci_driver = { | 2948 | static struct pci_driver net2280_pci_driver = { |
2949 | .name = (char *) driver_name, | 2949 | .name = (char *) driver_name, |
2950 | .id_table = pci_ids, | 2950 | .id_table = pci_ids, |
2951 | .owner = THIS_MODULE, | ||
2951 | 2952 | ||
2952 | .probe = net2280_probe, | 2953 | .probe = net2280_probe, |
2953 | .remove = net2280_remove, | 2954 | .remove = net2280_remove, |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b7885dc0f42f..41c96b0afbb3 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -691,7 +691,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) | |||
691 | } | 691 | } |
692 | 692 | ||
693 | static void | 693 | static void |
694 | finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status) | 694 | finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) |
695 | { | 695 | { |
696 | u16 count; | 696 | u16 count; |
697 | 697 | ||
@@ -699,6 +699,8 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status) | |||
699 | ep->dma_counter = (u16) (req->req.dma + req->req.actual); | 699 | ep->dma_counter = (u16) (req->req.dma + req->req.actual); |
700 | count = dma_dest_len(ep, req->req.dma + req->req.actual); | 700 | count = dma_dest_len(ep, req->req.dma + req->req.actual); |
701 | count += req->req.actual; | 701 | count += req->req.actual; |
702 | if (one) | ||
703 | count--; | ||
702 | if (count <= req->req.length) | 704 | if (count <= req->req.length) |
703 | req->req.actual = count; | 705 | req->req.actual = count; |
704 | 706 | ||
@@ -747,7 +749,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) | |||
747 | if (!list_empty(&ep->queue)) { | 749 | if (!list_empty(&ep->queue)) { |
748 | req = container_of(ep->queue.next, | 750 | req = container_of(ep->queue.next, |
749 | struct omap_req, queue); | 751 | struct omap_req, queue); |
750 | finish_out_dma(ep, req, 0); | 752 | finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB); |
751 | } | 753 | } |
752 | UDC_IRQ_SRC_REG = UDC_RXN_EOT; | 754 | UDC_IRQ_SRC_REG = UDC_RXN_EOT; |
753 | 755 | ||
@@ -925,7 +927,7 @@ static void dma_channel_release(struct omap_ep *ep) | |||
925 | while (UDC_RXDMA_CFG_REG & mask) | 927 | while (UDC_RXDMA_CFG_REG & mask) |
926 | udelay(10); | 928 | udelay(10); |
927 | if (req) | 929 | if (req) |
928 | finish_out_dma(ep, req, -ECONNRESET); | 930 | finish_out_dma(ep, req, -ECONNRESET, 0); |
929 | } | 931 | } |
930 | omap_free_dma(ep->lch); | 932 | omap_free_dma(ep->lch); |
931 | ep->dma_channel = 0; | 933 | ep->dma_channel = 0; |
@@ -1786,8 +1788,12 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) | |||
1786 | udc->driver->suspend(&udc->gadget); | 1788 | udc->driver->suspend(&udc->gadget); |
1787 | spin_lock(&udc->lock); | 1789 | spin_lock(&udc->lock); |
1788 | } | 1790 | } |
1791 | if (udc->transceiver) | ||
1792 | otg_set_suspend(udc->transceiver, 1); | ||
1789 | } else { | 1793 | } else { |
1790 | VDBG("resume\n"); | 1794 | VDBG("resume\n"); |
1795 | if (udc->transceiver) | ||
1796 | otg_set_suspend(udc->transceiver, 0); | ||
1791 | if (udc->gadget.speed == USB_SPEED_FULL | 1797 | if (udc->gadget.speed == USB_SPEED_FULL |
1792 | && udc->driver->resume) { | 1798 | && udc->driver->resume) { |
1793 | spin_unlock(&udc->lock); | 1799 | spin_unlock(&udc->lock); |
@@ -2943,6 +2949,7 @@ static int omap_udc_resume(struct device *dev) | |||
2943 | 2949 | ||
2944 | static struct device_driver udc_driver = { | 2950 | static struct device_driver udc_driver = { |
2945 | .name = (char *) driver_name, | 2951 | .name = (char *) driver_name, |
2952 | .owner = THIS_MODULE, | ||
2946 | .bus = &platform_bus_type, | 2953 | .bus = &platform_bus_type, |
2947 | .probe = omap_udc_probe, | 2954 | .probe = omap_udc_probe, |
2948 | .remove = __exit_p(omap_udc_remove), | 2955 | .remove = __exit_p(omap_udc_remove), |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 647028590b23..f83a9262f953 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -2631,6 +2631,7 @@ static int pxa2xx_udc_resume(struct device *dev) | |||
2631 | 2631 | ||
2632 | static struct device_driver udc_driver = { | 2632 | static struct device_driver udc_driver = { |
2633 | .name = "pxa2xx-udc", | 2633 | .name = "pxa2xx-udc", |
2634 | .owner = THIS_MODULE, | ||
2634 | .bus = &platform_bus_type, | 2635 | .bus = &platform_bus_type, |
2635 | .probe = pxa2xx_udc_probe, | 2636 | .probe = pxa2xx_udc_probe, |
2636 | .shutdown = pxa2xx_udc_shutdown, | 2637 | .shutdown = pxa2xx_udc_shutdown, |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index ec9c424f1d97..6c58636e914b 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -1302,6 +1302,7 @@ static struct usb_gadget_driver zero_driver = { | |||
1302 | 1302 | ||
1303 | .driver = { | 1303 | .driver = { |
1304 | .name = (char *) shortname, | 1304 | .name = (char *) shortname, |
1305 | .owner = THIS_MODULE, | ||
1305 | // .shutdown = ... | 1306 | // .shutdown = ... |
1306 | // .suspend = ... | 1307 | // .suspend = ... |
1307 | // .resume = ... | 1308 | // .resume = ... |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 350d14fc1cc9..58321d3f314c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | # | 1 | # |
2 | # Makefile for USB Host Controller Driver | 2 | # Makefile for USB Host Controller Drivers |
3 | # framework and drivers | ||
4 | # | 3 | # |
5 | 4 | ||
5 | obj-$(CONFIG_PCI) += pci-quirks.o | ||
6 | |||
6 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
7 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o | 8 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o |
8 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 9 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f5eb9e7b5b18..af3c05eb86fc 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *ehci) | |||
182 | { | 182 | { |
183 | u32 temp = readl (&ehci->regs->status); | 183 | u32 temp = readl (&ehci->regs->status); |
184 | 184 | ||
185 | /* disable any irqs left enabled by previous code */ | ||
186 | writel (0, &ehci->regs->intr_enable); | ||
187 | |||
185 | if ((temp & STS_HALT) != 0) | 188 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 189 | return 0; |
187 | 190 | ||
@@ -297,50 +300,17 @@ static void ehci_watchdog (unsigned long param) | |||
297 | spin_unlock_irqrestore (&ehci->lock, flags); | 300 | spin_unlock_irqrestore (&ehci->lock, flags); |
298 | } | 301 | } |
299 | 302 | ||
300 | #ifdef CONFIG_PCI | 303 | /* Reboot notifiers kick in for silicon on any bus (not just pci, etc). |
301 | 304 | * This forcibly disables dma and IRQs, helping kexec and other cases | |
302 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | 305 | * where the next system software may expect clean state. |
303 | * off the controller (maybe it can boot from highspeed USB disks). | ||
304 | */ | 306 | */ |
305 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | ||
306 | { | ||
307 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
308 | |||
309 | /* always say Linux will own the hardware */ | ||
310 | pci_write_config_byte(pdev, where + 3, 1); | ||
311 | |||
312 | /* maybe wait a while for BIOS to respond */ | ||
313 | if (cap & (1 << 16)) { | ||
314 | int msec = 5000; | ||
315 | |||
316 | do { | ||
317 | msleep(10); | ||
318 | msec -= 10; | ||
319 | pci_read_config_dword(pdev, where, &cap); | ||
320 | } while ((cap & (1 << 16)) && msec); | ||
321 | if (cap & (1 << 16)) { | ||
322 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
323 | where, cap); | ||
324 | // some BIOS versions seem buggy... | ||
325 | // return 1; | ||
326 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | ||
327 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
328 | pci_write_config_dword(pdev, where + 4, 0); | ||
329 | pci_write_config_byte(pdev, where + 2, 0); | ||
330 | } else | ||
331 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
332 | } | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | #endif | ||
337 | |||
338 | static int | 307 | static int |
339 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) | 308 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) |
340 | { | 309 | { |
341 | struct ehci_hcd *ehci; | 310 | struct ehci_hcd *ehci; |
342 | 311 | ||
343 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); | 312 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); |
313 | (void) ehci_halt (ehci); | ||
344 | 314 | ||
345 | /* make BIOS/etc use companion controller during reboot */ | 315 | /* make BIOS/etc use companion controller during reboot */ |
346 | writel (0, &ehci->regs->configured_flag); | 316 | writel (0, &ehci->regs->configured_flag); |
@@ -363,156 +333,90 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | |||
363 | msleep(20); | 333 | msleep(20); |
364 | } | 334 | } |
365 | 335 | ||
336 | /*-------------------------------------------------------------------------*/ | ||
337 | |||
338 | /* | ||
339 | * ehci_work is called from some interrupts, timers, and so on. | ||
340 | * it calls driver completion functions, after dropping ehci->lock. | ||
341 | */ | ||
342 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
343 | { | ||
344 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
345 | if (ehci->reclaim_ready) | ||
346 | end_unlink_async (ehci, regs); | ||
347 | |||
348 | /* another CPU may drop ehci->lock during a schedule scan while | ||
349 | * it reports urb completions. this flag guards against bogus | ||
350 | * attempts at re-entrant schedule scanning. | ||
351 | */ | ||
352 | if (ehci->scanning) | ||
353 | return; | ||
354 | ehci->scanning = 1; | ||
355 | scan_async (ehci, regs); | ||
356 | if (ehci->next_uframe != -1) | ||
357 | scan_periodic (ehci, regs); | ||
358 | ehci->scanning = 0; | ||
366 | 359 | ||
367 | /* called by khubd or root hub init threads */ | 360 | /* the IO watchdog guards against hardware or driver bugs that |
361 | * misplace IRQs, and should let us run completely without IRQs. | ||
362 | * such lossage has been observed on both VT6202 and VT8235. | ||
363 | */ | ||
364 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
365 | (ehci->async->qh_next.ptr != NULL || | ||
366 | ehci->periodic_sched != 0)) | ||
367 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
368 | } | ||
368 | 369 | ||
369 | static int ehci_hc_reset (struct usb_hcd *hcd) | 370 | static void ehci_stop (struct usb_hcd *hcd) |
370 | { | 371 | { |
371 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 372 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
372 | u32 temp; | ||
373 | unsigned count = 256/4; | ||
374 | 373 | ||
375 | spin_lock_init (&ehci->lock); | 374 | ehci_dbg (ehci, "stop\n"); |
376 | 375 | ||
377 | ehci->caps = hcd->regs; | 376 | /* Turn off port power on all root hub ports. */ |
378 | ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); | 377 | ehci_port_power (ehci, 0); |
379 | dbg_hcs_params (ehci, "reset"); | ||
380 | dbg_hcc_params (ehci, "reset"); | ||
381 | 378 | ||
382 | /* cache this readonly data; minimize chip reads */ | 379 | /* no more interrupts ... */ |
383 | ehci->hcs_params = readl (&ehci->caps->hcs_params); | 380 | del_timer_sync (&ehci->watchdog); |
384 | 381 | ||
385 | #ifdef CONFIG_PCI | 382 | spin_lock_irq(&ehci->lock); |
386 | if (hcd->self.controller->bus == &pci_bus_type) { | 383 | if (HC_IS_RUNNING (hcd->state)) |
387 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 384 | ehci_quiesce (ehci); |
388 | 385 | ||
389 | switch (pdev->vendor) { | 386 | ehci_reset (ehci); |
390 | case PCI_VENDOR_ID_TDI: | 387 | writel (0, &ehci->regs->intr_enable); |
391 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 388 | spin_unlock_irq(&ehci->lock); |
392 | ehci->is_tdi_rh_tt = 1; | ||
393 | tdi_reset (ehci); | ||
394 | } | ||
395 | break; | ||
396 | case PCI_VENDOR_ID_AMD: | ||
397 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
398 | if (pdev->device == 0x7463) { | ||
399 | ehci_info (ehci, "ignoring AMD8111 (errata)\n"); | ||
400 | return -EIO; | ||
401 | } | ||
402 | break; | ||
403 | case PCI_VENDOR_ID_NVIDIA: | ||
404 | /* NVidia reports that certain chips don't handle | ||
405 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
406 | * data buffer, and periodic schedule are normal.) | ||
407 | */ | ||
408 | switch (pdev->device) { | ||
409 | case 0x003c: /* MCP04 */ | ||
410 | case 0x005b: /* CK804 */ | ||
411 | case 0x00d8: /* CK8 */ | ||
412 | case 0x00e8: /* CK8S */ | ||
413 | if (pci_set_consistent_dma_mask(pdev, | ||
414 | DMA_31BIT_MASK) < 0) | ||
415 | ehci_warn (ehci, "can't enable NVidia " | ||
416 | "workaround for >2GB RAM\n"); | ||
417 | break; | ||
418 | } | ||
419 | break; | ||
420 | } | ||
421 | 389 | ||
422 | /* optional debug port, normally in the first BAR */ | 390 | /* let companion controllers work when we aren't */ |
423 | temp = pci_find_capability (pdev, 0x0a); | 391 | writel (0, &ehci->regs->configured_flag); |
424 | if (temp) { | 392 | unregister_reboot_notifier (&ehci->reboot_notifier); |
425 | pci_read_config_dword(pdev, temp, &temp); | ||
426 | temp >>= 16; | ||
427 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
428 | temp &= 0x1fff; | ||
429 | ehci->debug = hcd->regs + temp; | ||
430 | temp = readl (&ehci->debug->control); | ||
431 | ehci_info (ehci, "debug port %d%s\n", | ||
432 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
433 | (temp & DBGP_ENABLED) | ||
434 | ? " IN USE" | ||
435 | : ""); | ||
436 | if (!(temp & DBGP_ENABLED)) | ||
437 | ehci->debug = NULL; | ||
438 | } | ||
439 | } | ||
440 | 393 | ||
441 | temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 394 | remove_debug_files (ehci); |
442 | } else | ||
443 | temp = 0; | ||
444 | |||
445 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
446 | while (temp && count--) { | ||
447 | u32 cap; | ||
448 | |||
449 | pci_read_config_dword (to_pci_dev(hcd->self.controller), | ||
450 | temp, &cap); | ||
451 | ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); | ||
452 | switch (cap & 0xff) { | ||
453 | case 1: /* BIOS/SMM/... handoff */ | ||
454 | if (bios_handoff (ehci, temp, cap) != 0) | ||
455 | return -EOPNOTSUPP; | ||
456 | break; | ||
457 | case 0: /* illegal reserved capability */ | ||
458 | ehci_warn (ehci, "illegal capability!\n"); | ||
459 | cap = 0; | ||
460 | /* FALLTHROUGH */ | ||
461 | default: /* unknown */ | ||
462 | break; | ||
463 | } | ||
464 | temp = (cap >> 8) & 0xff; | ||
465 | } | ||
466 | if (!count) { | ||
467 | ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); | ||
468 | return -EIO; | ||
469 | } | ||
470 | if (ehci_is_TDI(ehci)) | ||
471 | ehci_reset (ehci); | ||
472 | #endif | ||
473 | 395 | ||
474 | ehci_port_power (ehci, 0); | 396 | /* root hub is shut down separately (first, when possible) */ |
397 | spin_lock_irq (&ehci->lock); | ||
398 | if (ehci->async) | ||
399 | ehci_work (ehci, NULL); | ||
400 | spin_unlock_irq (&ehci->lock); | ||
401 | ehci_mem_cleanup (ehci); | ||
475 | 402 | ||
476 | /* at least the Genesys GL880S needs fixup here */ | 403 | #ifdef EHCI_STATS |
477 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 404 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", |
478 | temp &= 0x0f; | 405 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, |
479 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | 406 | ehci->stats.lost_iaa); |
480 | ehci_dbg (ehci, "bogus port configuration: " | 407 | ehci_dbg (ehci, "complete %ld unlink %ld\n", |
481 | "cc=%d x pcc=%d < ports=%d\n", | 408 | ehci->stats.complete, ehci->stats.unlink); |
482 | HCS_N_CC(ehci->hcs_params), | ||
483 | HCS_N_PCC(ehci->hcs_params), | ||
484 | HCS_N_PORTS(ehci->hcs_params)); | ||
485 | |||
486 | #ifdef CONFIG_PCI | ||
487 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
488 | struct pci_dev *pdev; | ||
489 | |||
490 | pdev = to_pci_dev(hcd->self.controller); | ||
491 | switch (pdev->vendor) { | ||
492 | case 0x17a0: /* GENESYS */ | ||
493 | /* GL880S: should be PORTS=2 */ | ||
494 | temp |= (ehci->hcs_params & ~0xf); | ||
495 | ehci->hcs_params = temp; | ||
496 | break; | ||
497 | case PCI_VENDOR_ID_NVIDIA: | ||
498 | /* NF4: should be PCC=10 */ | ||
499 | break; | ||
500 | } | ||
501 | } | ||
502 | #endif | 409 | #endif |
503 | } | ||
504 | 410 | ||
505 | /* force HC to halt state */ | 411 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); |
506 | return ehci_halt (ehci); | ||
507 | } | 412 | } |
508 | 413 | ||
509 | static int ehci_start (struct usb_hcd *hcd) | 414 | static int ehci_run (struct usb_hcd *hcd) |
510 | { | 415 | { |
511 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 416 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
512 | u32 temp; | 417 | u32 temp; |
513 | int retval; | 418 | int retval; |
514 | u32 hcc_params; | 419 | u32 hcc_params; |
515 | u8 sbrn = 0; | ||
516 | int first; | 420 | int first; |
517 | 421 | ||
518 | /* skip some things on restart paths */ | 422 | /* skip some things on restart paths */ |
@@ -551,27 +455,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
551 | } | 455 | } |
552 | writel (ehci->periodic_dma, &ehci->regs->frame_list); | 456 | writel (ehci->periodic_dma, &ehci->regs->frame_list); |
553 | 457 | ||
554 | #ifdef CONFIG_PCI | ||
555 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
556 | struct pci_dev *pdev; | ||
557 | u16 port_wake; | ||
558 | |||
559 | pdev = to_pci_dev(hcd->self.controller); | ||
560 | |||
561 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
562 | pci_read_config_byte(pdev, 0x60, &sbrn); | ||
563 | |||
564 | /* port wake capability, reported by boot firmware */ | ||
565 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
566 | hcd->can_wakeup = (port_wake & 1) != 0; | ||
567 | |||
568 | /* help hc dma work well with cachelines */ | ||
569 | retval = pci_set_mwi(pdev); | ||
570 | if (retval) | ||
571 | ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); | ||
572 | } | ||
573 | #endif | ||
574 | |||
575 | /* | 458 | /* |
576 | * dedicate a qh for the async ring head, since we couldn't unlink | 459 | * dedicate a qh for the async ring head, since we couldn't unlink |
577 | * a 'real' qh without stopping the async schedule [4.8]. use it | 460 | * a 'real' qh without stopping the async schedule [4.8]. use it |
@@ -667,7 +550,7 @@ static int ehci_start (struct usb_hcd *hcd) | |||
667 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 550 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); |
668 | ehci_info (ehci, | 551 | ehci_info (ehci, |
669 | "USB %x.%x %s, EHCI %x.%02x, driver %s\n", | 552 | "USB %x.%x %s, EHCI %x.%02x, driver %s\n", |
670 | ((sbrn & 0xf0)>>4), (sbrn & 0x0f), | 553 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
671 | first ? "initialized" : "restarted", | 554 | first ? "initialized" : "restarted", |
672 | temp >> 8, temp & 0xff, DRIVER_VERSION); | 555 | temp >> 8, temp & 0xff, DRIVER_VERSION); |
673 | 556 | ||
@@ -679,188 +562,6 @@ static int ehci_start (struct usb_hcd *hcd) | |||
679 | return 0; | 562 | return 0; |
680 | } | 563 | } |
681 | 564 | ||
682 | /* always called by thread; normally rmmod */ | ||
683 | |||
684 | static void ehci_stop (struct usb_hcd *hcd) | ||
685 | { | ||
686 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
687 | |||
688 | ehci_dbg (ehci, "stop\n"); | ||
689 | |||
690 | /* Turn off port power on all root hub ports. */ | ||
691 | ehci_port_power (ehci, 0); | ||
692 | |||
693 | /* no more interrupts ... */ | ||
694 | del_timer_sync (&ehci->watchdog); | ||
695 | |||
696 | spin_lock_irq(&ehci->lock); | ||
697 | if (HC_IS_RUNNING (hcd->state)) | ||
698 | ehci_quiesce (ehci); | ||
699 | |||
700 | ehci_reset (ehci); | ||
701 | writel (0, &ehci->regs->intr_enable); | ||
702 | spin_unlock_irq(&ehci->lock); | ||
703 | |||
704 | /* let companion controllers work when we aren't */ | ||
705 | writel (0, &ehci->regs->configured_flag); | ||
706 | unregister_reboot_notifier (&ehci->reboot_notifier); | ||
707 | |||
708 | remove_debug_files (ehci); | ||
709 | |||
710 | /* root hub is shut down separately (first, when possible) */ | ||
711 | spin_lock_irq (&ehci->lock); | ||
712 | if (ehci->async) | ||
713 | ehci_work (ehci, NULL); | ||
714 | spin_unlock_irq (&ehci->lock); | ||
715 | ehci_mem_cleanup (ehci); | ||
716 | |||
717 | #ifdef EHCI_STATS | ||
718 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", | ||
719 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, | ||
720 | ehci->stats.lost_iaa); | ||
721 | ehci_dbg (ehci, "complete %ld unlink %ld\n", | ||
722 | ehci->stats.complete, ehci->stats.unlink); | ||
723 | #endif | ||
724 | |||
725 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | ||
726 | } | ||
727 | |||
728 | static int ehci_get_frame (struct usb_hcd *hcd) | ||
729 | { | ||
730 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
731 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | ||
732 | } | ||
733 | |||
734 | /*-------------------------------------------------------------------------*/ | ||
735 | |||
736 | #ifdef CONFIG_PM | ||
737 | |||
738 | /* suspend/resume, section 4.3 */ | ||
739 | |||
740 | /* These routines rely on the bus (pci, platform, etc) | ||
741 | * to handle powerdown and wakeup, and currently also on | ||
742 | * transceivers that don't need any software attention to set up | ||
743 | * the right sort of wakeup. | ||
744 | */ | ||
745 | |||
746 | static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) | ||
747 | { | ||
748 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
749 | |||
750 | if (time_before (jiffies, ehci->next_statechange)) | ||
751 | msleep (100); | ||
752 | |||
753 | #ifdef CONFIG_USB_SUSPEND | ||
754 | (void) usb_suspend_device (hcd->self.root_hub, message); | ||
755 | #else | ||
756 | usb_lock_device (hcd->self.root_hub); | ||
757 | (void) ehci_hub_suspend (hcd); | ||
758 | usb_unlock_device (hcd->self.root_hub); | ||
759 | #endif | ||
760 | |||
761 | // save (PCI) FLADJ in case of Vaux power loss | ||
762 | // ... we'd only use it to handle clock skew | ||
763 | |||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int ehci_resume (struct usb_hcd *hcd) | ||
768 | { | ||
769 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
770 | unsigned port; | ||
771 | struct usb_device *root = hcd->self.root_hub; | ||
772 | int retval = -EINVAL; | ||
773 | |||
774 | // maybe restore (PCI) FLADJ | ||
775 | |||
776 | if (time_before (jiffies, ehci->next_statechange)) | ||
777 | msleep (100); | ||
778 | |||
779 | /* If any port is suspended (or owned by the companion), | ||
780 | * we know we can/must resume the HC (and mustn't reset it). | ||
781 | */ | ||
782 | for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { | ||
783 | u32 status; | ||
784 | port--; | ||
785 | status = readl (&ehci->regs->port_status [port]); | ||
786 | if (!(status & PORT_POWER)) | ||
787 | continue; | ||
788 | if (status & (PORT_SUSPEND | PORT_OWNER)) { | ||
789 | down (&hcd->self.root_hub->serialize); | ||
790 | retval = ehci_hub_resume (hcd); | ||
791 | up (&hcd->self.root_hub->serialize); | ||
792 | break; | ||
793 | } | ||
794 | if (!root->children [port]) | ||
795 | continue; | ||
796 | dbg_port (ehci, __FUNCTION__, port + 1, status); | ||
797 | usb_set_device_state (root->children[port], | ||
798 | USB_STATE_NOTATTACHED); | ||
799 | } | ||
800 | |||
801 | /* Else reset, to cope with power loss or flush-to-storage | ||
802 | * style "resume" having activated BIOS during reboot. | ||
803 | */ | ||
804 | if (port == 0) { | ||
805 | (void) ehci_halt (ehci); | ||
806 | (void) ehci_reset (ehci); | ||
807 | (void) ehci_hc_reset (hcd); | ||
808 | |||
809 | /* emptying the schedule aborts any urbs */ | ||
810 | spin_lock_irq (&ehci->lock); | ||
811 | if (ehci->reclaim) | ||
812 | ehci->reclaim_ready = 1; | ||
813 | ehci_work (ehci, NULL); | ||
814 | spin_unlock_irq (&ehci->lock); | ||
815 | |||
816 | /* restart; khubd will disconnect devices */ | ||
817 | retval = ehci_start (hcd); | ||
818 | |||
819 | /* here we "know" root ports should always stay powered; | ||
820 | * but some controllers may lose all power. | ||
821 | */ | ||
822 | ehci_port_power (ehci, 1); | ||
823 | } | ||
824 | |||
825 | return retval; | ||
826 | } | ||
827 | |||
828 | #endif | ||
829 | |||
830 | /*-------------------------------------------------------------------------*/ | ||
831 | |||
832 | /* | ||
833 | * ehci_work is called from some interrupts, timers, and so on. | ||
834 | * it calls driver completion functions, after dropping ehci->lock. | ||
835 | */ | ||
836 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
837 | { | ||
838 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
839 | if (ehci->reclaim_ready) | ||
840 | end_unlink_async (ehci, regs); | ||
841 | |||
842 | /* another CPU may drop ehci->lock during a schedule scan while | ||
843 | * it reports urb completions. this flag guards against bogus | ||
844 | * attempts at re-entrant schedule scanning. | ||
845 | */ | ||
846 | if (ehci->scanning) | ||
847 | return; | ||
848 | ehci->scanning = 1; | ||
849 | scan_async (ehci, regs); | ||
850 | if (ehci->next_uframe != -1) | ||
851 | scan_periodic (ehci, regs); | ||
852 | ehci->scanning = 0; | ||
853 | |||
854 | /* the IO watchdog guards against hardware or driver bugs that | ||
855 | * misplace IRQs, and should let us run completely without IRQs. | ||
856 | * such lossage has been observed on both VT6202 and VT8235. | ||
857 | */ | ||
858 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
859 | (ehci->async->qh_next.ptr != NULL || | ||
860 | ehci->periodic_sched != 0)) | ||
861 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
862 | } | ||
863 | |||
864 | /*-------------------------------------------------------------------------*/ | 565 | /*-------------------------------------------------------------------------*/ |
865 | 566 | ||
866 | static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | 567 | static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) |
@@ -1171,106 +872,24 @@ done: | |||
1171 | return; | 872 | return; |
1172 | } | 873 | } |
1173 | 874 | ||
1174 | /*-------------------------------------------------------------------------*/ | 875 | static int ehci_get_frame (struct usb_hcd *hcd) |
1175 | 876 | { | |
1176 | static const struct hc_driver ehci_driver = { | 877 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
1177 | .description = hcd_name, | 878 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; |
1178 | .product_desc = "EHCI Host Controller", | 879 | } |
1179 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
1180 | |||
1181 | /* | ||
1182 | * generic hardware linkage | ||
1183 | */ | ||
1184 | .irq = ehci_irq, | ||
1185 | .flags = HCD_MEMORY | HCD_USB2, | ||
1186 | |||
1187 | /* | ||
1188 | * basic lifecycle operations | ||
1189 | */ | ||
1190 | .reset = ehci_hc_reset, | ||
1191 | .start = ehci_start, | ||
1192 | #ifdef CONFIG_PM | ||
1193 | .suspend = ehci_suspend, | ||
1194 | .resume = ehci_resume, | ||
1195 | #endif | ||
1196 | .stop = ehci_stop, | ||
1197 | |||
1198 | /* | ||
1199 | * managing i/o requests and associated device resources | ||
1200 | */ | ||
1201 | .urb_enqueue = ehci_urb_enqueue, | ||
1202 | .urb_dequeue = ehci_urb_dequeue, | ||
1203 | .endpoint_disable = ehci_endpoint_disable, | ||
1204 | |||
1205 | /* | ||
1206 | * scheduling support | ||
1207 | */ | ||
1208 | .get_frame_number = ehci_get_frame, | ||
1209 | |||
1210 | /* | ||
1211 | * root hub support | ||
1212 | */ | ||
1213 | .hub_status_data = ehci_hub_status_data, | ||
1214 | .hub_control = ehci_hub_control, | ||
1215 | .hub_suspend = ehci_hub_suspend, | ||
1216 | .hub_resume = ehci_hub_resume, | ||
1217 | }; | ||
1218 | 880 | ||
1219 | /*-------------------------------------------------------------------------*/ | 881 | /*-------------------------------------------------------------------------*/ |
1220 | 882 | ||
1221 | /* EHCI 1.0 doesn't require PCI */ | ||
1222 | |||
1223 | #ifdef CONFIG_PCI | ||
1224 | |||
1225 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
1226 | static const struct pci_device_id pci_ids [] = { { | ||
1227 | /* handle any USB 2.0 EHCI controller */ | ||
1228 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
1229 | .driver_data = (unsigned long) &ehci_driver, | ||
1230 | }, | ||
1231 | { /* end: all zeroes */ } | ||
1232 | }; | ||
1233 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
1234 | |||
1235 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
1236 | static struct pci_driver ehci_pci_driver = { | ||
1237 | .name = (char *) hcd_name, | ||
1238 | .id_table = pci_ids, | ||
1239 | |||
1240 | .probe = usb_hcd_pci_probe, | ||
1241 | .remove = usb_hcd_pci_remove, | ||
1242 | |||
1243 | #ifdef CONFIG_PM | ||
1244 | .suspend = usb_hcd_pci_suspend, | ||
1245 | .resume = usb_hcd_pci_resume, | ||
1246 | #endif | ||
1247 | }; | ||
1248 | |||
1249 | #endif /* PCI */ | ||
1250 | |||
1251 | |||
1252 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 883 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
1253 | 884 | ||
1254 | MODULE_DESCRIPTION (DRIVER_INFO); | 885 | MODULE_DESCRIPTION (DRIVER_INFO); |
1255 | MODULE_AUTHOR (DRIVER_AUTHOR); | 886 | MODULE_AUTHOR (DRIVER_AUTHOR); |
1256 | MODULE_LICENSE ("GPL"); | 887 | MODULE_LICENSE ("GPL"); |
1257 | 888 | ||
1258 | static int __init init (void) | 889 | #ifdef CONFIG_PCI |
1259 | { | 890 | #include "ehci-pci.c" |
1260 | if (usb_disabled()) | 891 | #endif |
1261 | return -ENODEV; | ||
1262 | |||
1263 | pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
1264 | hcd_name, | ||
1265 | sizeof (struct ehci_qh), sizeof (struct ehci_qtd), | ||
1266 | sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); | ||
1267 | |||
1268 | return pci_register_driver (&ehci_pci_driver); | ||
1269 | } | ||
1270 | module_init (init); | ||
1271 | 892 | ||
1272 | static void __exit cleanup (void) | 893 | #if !defined(CONFIG_PCI) |
1273 | { | 894 | #error "missing bus glue for ehci-hcd" |
1274 | pci_unregister_driver (&ehci_pci_driver); | 895 | #endif |
1275 | } | ||
1276 | module_exit (cleanup); | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 18d3f2270316..88cb4ada686e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_PM | 31 | #ifdef CONFIG_PM |
32 | 32 | ||
33 | static int ehci_hub_suspend (struct usb_hcd *hcd) | 33 | static int ehci_bus_suspend (struct usb_hcd *hcd) |
34 | { | 34 | { |
35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
36 | int port; | 36 | int port; |
@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) | |||
83 | 83 | ||
84 | 84 | ||
85 | /* caller has locked the root hub, and should reset/reinit on error */ | 85 | /* caller has locked the root hub, and should reset/reinit on error */ |
86 | static int ehci_hub_resume (struct usb_hcd *hcd) | 86 | static int ehci_bus_resume (struct usb_hcd *hcd) |
87 | { | 87 | { |
88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
89 | u32 temp; | 89 | u32 temp; |
@@ -159,8 +159,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
159 | 159 | ||
160 | #else | 160 | #else |
161 | 161 | ||
162 | #define ehci_hub_suspend NULL | 162 | #define ehci_bus_suspend NULL |
163 | #define ehci_hub_resume NULL | 163 | #define ehci_bus_resume NULL |
164 | 164 | ||
165 | #endif /* CONFIG_PM */ | 165 | #endif /* CONFIG_PM */ |
166 | 166 | ||
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c new file mode 100644 index 000000000000..145008853966 --- /dev/null +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -0,0 +1,415 @@ | |||
1 | /* | ||
2 | * EHCI HCD (Host Controller Driver) PCI Bus Glue. | ||
3 | * | ||
4 | * Copyright (c) 2000-2004 by David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software Foundation, | ||
18 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CONFIG_PCI | ||
22 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | ||
23 | #endif | ||
24 | |||
25 | /*-------------------------------------------------------------------------*/ | ||
26 | |||
27 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | ||
28 | * off the controller (maybe it can boot from highspeed USB disks). | ||
29 | */ | ||
30 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | ||
31 | { | ||
32 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
33 | |||
34 | /* always say Linux will own the hardware */ | ||
35 | pci_write_config_byte(pdev, where + 3, 1); | ||
36 | |||
37 | /* maybe wait a while for BIOS to respond */ | ||
38 | if (cap & (1 << 16)) { | ||
39 | int msec = 5000; | ||
40 | |||
41 | do { | ||
42 | msleep(10); | ||
43 | msec -= 10; | ||
44 | pci_read_config_dword(pdev, where, &cap); | ||
45 | } while ((cap & (1 << 16)) && msec); | ||
46 | if (cap & (1 << 16)) { | ||
47 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
48 | where, cap); | ||
49 | // some BIOS versions seem buggy... | ||
50 | // return 1; | ||
51 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | ||
52 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
53 | pci_write_config_dword(pdev, where + 4, 0); | ||
54 | pci_write_config_byte(pdev, where + 2, 0); | ||
55 | } else | ||
56 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
57 | } | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | /* called by khubd or root hub init threads */ | ||
62 | static int ehci_pci_reset (struct usb_hcd *hcd) | ||
63 | { | ||
64 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
65 | u32 temp; | ||
66 | unsigned count = 256/4; | ||
67 | |||
68 | spin_lock_init (&ehci->lock); | ||
69 | |||
70 | ehci->caps = hcd->regs; | ||
71 | ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); | ||
72 | dbg_hcs_params (ehci, "reset"); | ||
73 | dbg_hcc_params (ehci, "reset"); | ||
74 | |||
75 | /* cache this readonly data; minimize chip reads */ | ||
76 | ehci->hcs_params = readl (&ehci->caps->hcs_params); | ||
77 | |||
78 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
79 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
80 | |||
81 | switch (pdev->vendor) { | ||
82 | case PCI_VENDOR_ID_TDI: | ||
83 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | ||
84 | ehci->is_tdi_rh_tt = 1; | ||
85 | tdi_reset (ehci); | ||
86 | } | ||
87 | break; | ||
88 | case PCI_VENDOR_ID_AMD: | ||
89 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
90 | if (pdev->device == 0x7463) { | ||
91 | ehci_info (ehci, "ignoring AMD8111 (errata)\n"); | ||
92 | return -EIO; | ||
93 | } | ||
94 | break; | ||
95 | case PCI_VENDOR_ID_NVIDIA: | ||
96 | /* NVidia reports that certain chips don't handle | ||
97 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
98 | * data buffer, and periodic schedule are normal.) | ||
99 | */ | ||
100 | switch (pdev->device) { | ||
101 | case 0x003c: /* MCP04 */ | ||
102 | case 0x005b: /* CK804 */ | ||
103 | case 0x00d8: /* CK8 */ | ||
104 | case 0x00e8: /* CK8S */ | ||
105 | if (pci_set_consistent_dma_mask(pdev, | ||
106 | DMA_31BIT_MASK) < 0) | ||
107 | ehci_warn (ehci, "can't enable NVidia " | ||
108 | "workaround for >2GB RAM\n"); | ||
109 | break; | ||
110 | } | ||
111 | break; | ||
112 | } | ||
113 | |||
114 | /* optional debug port, normally in the first BAR */ | ||
115 | temp = pci_find_capability (pdev, 0x0a); | ||
116 | if (temp) { | ||
117 | pci_read_config_dword(pdev, temp, &temp); | ||
118 | temp >>= 16; | ||
119 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
120 | temp &= 0x1fff; | ||
121 | ehci->debug = hcd->regs + temp; | ||
122 | temp = readl (&ehci->debug->control); | ||
123 | ehci_info (ehci, "debug port %d%s\n", | ||
124 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
125 | (temp & DBGP_ENABLED) | ||
126 | ? " IN USE" | ||
127 | : ""); | ||
128 | if (!(temp & DBGP_ENABLED)) | ||
129 | ehci->debug = NULL; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | ||
134 | } else | ||
135 | temp = 0; | ||
136 | |||
137 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
138 | while (temp && count--) { | ||
139 | u32 cap; | ||
140 | |||
141 | pci_read_config_dword (to_pci_dev(hcd->self.controller), | ||
142 | temp, &cap); | ||
143 | ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); | ||
144 | switch (cap & 0xff) { | ||
145 | case 1: /* BIOS/SMM/... handoff */ | ||
146 | if (bios_handoff (ehci, temp, cap) != 0) | ||
147 | return -EOPNOTSUPP; | ||
148 | break; | ||
149 | case 0: /* illegal reserved capability */ | ||
150 | ehci_warn (ehci, "illegal capability!\n"); | ||
151 | cap = 0; | ||
152 | /* FALLTHROUGH */ | ||
153 | default: /* unknown */ | ||
154 | break; | ||
155 | } | ||
156 | temp = (cap >> 8) & 0xff; | ||
157 | } | ||
158 | if (!count) { | ||
159 | ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); | ||
160 | return -EIO; | ||
161 | } | ||
162 | if (ehci_is_TDI(ehci)) | ||
163 | ehci_reset (ehci); | ||
164 | |||
165 | ehci_port_power (ehci, 0); | ||
166 | |||
167 | /* at least the Genesys GL880S needs fixup here */ | ||
168 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | ||
169 | temp &= 0x0f; | ||
170 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | ||
171 | ehci_dbg (ehci, "bogus port configuration: " | ||
172 | "cc=%d x pcc=%d < ports=%d\n", | ||
173 | HCS_N_CC(ehci->hcs_params), | ||
174 | HCS_N_PCC(ehci->hcs_params), | ||
175 | HCS_N_PORTS(ehci->hcs_params)); | ||
176 | |||
177 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
178 | struct pci_dev *pdev; | ||
179 | |||
180 | pdev = to_pci_dev(hcd->self.controller); | ||
181 | switch (pdev->vendor) { | ||
182 | case 0x17a0: /* GENESYS */ | ||
183 | /* GL880S: should be PORTS=2 */ | ||
184 | temp |= (ehci->hcs_params & ~0xf); | ||
185 | ehci->hcs_params = temp; | ||
186 | break; | ||
187 | case PCI_VENDOR_ID_NVIDIA: | ||
188 | /* NF4: should be PCC=10 */ | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /* force HC to halt state */ | ||
195 | return ehci_halt (ehci); | ||
196 | } | ||
197 | |||
198 | static int ehci_pci_start (struct usb_hcd *hcd) | ||
199 | { | ||
200 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
201 | int result = 0; | ||
202 | |||
203 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
204 | struct pci_dev *pdev; | ||
205 | u16 port_wake; | ||
206 | |||
207 | pdev = to_pci_dev(hcd->self.controller); | ||
208 | |||
209 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
210 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | ||
211 | |||
212 | /* port wake capability, reported by boot firmware */ | ||
213 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
214 | hcd->can_wakeup = (port_wake & 1) != 0; | ||
215 | |||
216 | /* help hc dma work well with cachelines */ | ||
217 | result = pci_set_mwi(pdev); | ||
218 | if (result) | ||
219 | ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); | ||
220 | } | ||
221 | |||
222 | return ehci_run (hcd); | ||
223 | } | ||
224 | |||
225 | /* always called by thread; normally rmmod */ | ||
226 | |||
227 | static void ehci_pci_stop (struct usb_hcd *hcd) | ||
228 | { | ||
229 | ehci_stop (hcd); | ||
230 | } | ||
231 | |||
232 | /*-------------------------------------------------------------------------*/ | ||
233 | |||
234 | #ifdef CONFIG_PM | ||
235 | |||
236 | /* suspend/resume, section 4.3 */ | ||
237 | |||
238 | /* These routines rely on the bus (pci, platform, etc) | ||
239 | * to handle powerdown and wakeup, and currently also on | ||
240 | * transceivers that don't need any software attention to set up | ||
241 | * the right sort of wakeup. | ||
242 | */ | ||
243 | |||
244 | static int ehci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | ||
245 | { | ||
246 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
247 | |||
248 | if (time_before (jiffies, ehci->next_statechange)) | ||
249 | msleep (100); | ||
250 | |||
251 | #ifdef CONFIG_USB_SUSPEND | ||
252 | (void) usb_suspend_device (hcd->self.root_hub); | ||
253 | #else | ||
254 | usb_lock_device (hcd->self.root_hub); | ||
255 | (void) ehci_bus_suspend (hcd); | ||
256 | usb_unlock_device (hcd->self.root_hub); | ||
257 | #endif | ||
258 | |||
259 | // save (PCI) FLADJ in case of Vaux power loss | ||
260 | // ... we'd only use it to handle clock skew | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int ehci_pci_resume (struct usb_hcd *hcd) | ||
266 | { | ||
267 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
268 | unsigned port; | ||
269 | struct usb_device *root = hcd->self.root_hub; | ||
270 | int retval = -EINVAL; | ||
271 | |||
272 | // maybe restore (PCI) FLADJ | ||
273 | |||
274 | if (time_before (jiffies, ehci->next_statechange)) | ||
275 | msleep (100); | ||
276 | |||
277 | /* If any port is suspended (or owned by the companion), | ||
278 | * we know we can/must resume the HC (and mustn't reset it). | ||
279 | */ | ||
280 | for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { | ||
281 | u32 status; | ||
282 | port--; | ||
283 | status = readl (&ehci->regs->port_status [port]); | ||
284 | if (!(status & PORT_POWER)) | ||
285 | continue; | ||
286 | if (status & (PORT_SUSPEND | PORT_OWNER)) { | ||
287 | down (&hcd->self.root_hub->serialize); | ||
288 | retval = ehci_bus_resume (hcd); | ||
289 | up (&hcd->self.root_hub->serialize); | ||
290 | break; | ||
291 | } | ||
292 | if (!root->children [port]) | ||
293 | continue; | ||
294 | dbg_port (ehci, __FUNCTION__, port + 1, status); | ||
295 | usb_set_device_state (root->children[port], | ||
296 | USB_STATE_NOTATTACHED); | ||
297 | } | ||
298 | |||
299 | /* Else reset, to cope with power loss or flush-to-storage | ||
300 | * style "resume" having activated BIOS during reboot. | ||
301 | */ | ||
302 | if (port == 0) { | ||
303 | (void) ehci_halt (ehci); | ||
304 | (void) ehci_reset (ehci); | ||
305 | (void) ehci_pci_reset (hcd); | ||
306 | |||
307 | /* emptying the schedule aborts any urbs */ | ||
308 | spin_lock_irq (&ehci->lock); | ||
309 | if (ehci->reclaim) | ||
310 | ehci->reclaim_ready = 1; | ||
311 | ehci_work (ehci, NULL); | ||
312 | spin_unlock_irq (&ehci->lock); | ||
313 | |||
314 | /* restart; khubd will disconnect devices */ | ||
315 | retval = ehci_run (hcd); | ||
316 | |||
317 | /* here we "know" root ports should always stay powered; | ||
318 | * but some controllers may lose all power. | ||
319 | */ | ||
320 | ehci_port_power (ehci, 1); | ||
321 | } | ||
322 | |||
323 | return retval; | ||
324 | } | ||
325 | #endif | ||
326 | |||
327 | static const struct hc_driver ehci_pci_hc_driver = { | ||
328 | .description = hcd_name, | ||
329 | .product_desc = "EHCI Host Controller", | ||
330 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
331 | |||
332 | /* | ||
333 | * generic hardware linkage | ||
334 | */ | ||
335 | .irq = ehci_irq, | ||
336 | .flags = HCD_MEMORY | HCD_USB2, | ||
337 | |||
338 | /* | ||
339 | * basic lifecycle operations | ||
340 | */ | ||
341 | .reset = ehci_pci_reset, | ||
342 | .start = ehci_pci_start, | ||
343 | #ifdef CONFIG_PM | ||
344 | .suspend = ehci_pci_suspend, | ||
345 | .resume = ehci_pci_resume, | ||
346 | #endif | ||
347 | .stop = ehci_pci_stop, | ||
348 | |||
349 | /* | ||
350 | * managing i/o requests and associated device resources | ||
351 | */ | ||
352 | .urb_enqueue = ehci_urb_enqueue, | ||
353 | .urb_dequeue = ehci_urb_dequeue, | ||
354 | .endpoint_disable = ehci_endpoint_disable, | ||
355 | |||
356 | /* | ||
357 | * scheduling support | ||
358 | */ | ||
359 | .get_frame_number = ehci_get_frame, | ||
360 | |||
361 | /* | ||
362 | * root hub support | ||
363 | */ | ||
364 | .hub_status_data = ehci_hub_status_data, | ||
365 | .hub_control = ehci_hub_control, | ||
366 | .bus_suspend = ehci_bus_suspend, | ||
367 | .bus_resume = ehci_bus_resume, | ||
368 | }; | ||
369 | |||
370 | /*-------------------------------------------------------------------------*/ | ||
371 | |||
372 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
373 | static const struct pci_device_id pci_ids [] = { { | ||
374 | /* handle any USB 2.0 EHCI controller */ | ||
375 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
376 | .driver_data = (unsigned long) &ehci_pci_hc_driver, | ||
377 | }, | ||
378 | { /* end: all zeroes */ } | ||
379 | }; | ||
380 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
381 | |||
382 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
383 | static struct pci_driver ehci_pci_driver = { | ||
384 | .name = (char *) hcd_name, | ||
385 | .id_table = pci_ids, | ||
386 | .owner = THIS_MODULE, | ||
387 | |||
388 | .probe = usb_hcd_pci_probe, | ||
389 | .remove = usb_hcd_pci_remove, | ||
390 | |||
391 | #ifdef CONFIG_PM | ||
392 | .suspend = usb_hcd_pci_suspend, | ||
393 | .resume = usb_hcd_pci_resume, | ||
394 | #endif | ||
395 | }; | ||
396 | |||
397 | static int __init ehci_hcd_pci_init (void) | ||
398 | { | ||
399 | if (usb_disabled()) | ||
400 | return -ENODEV; | ||
401 | |||
402 | pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
403 | hcd_name, | ||
404 | sizeof (struct ehci_qh), sizeof (struct ehci_qtd), | ||
405 | sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); | ||
406 | |||
407 | return pci_register_driver (&ehci_pci_driver); | ||
408 | } | ||
409 | module_init (ehci_hcd_pci_init); | ||
410 | |||
411 | static void __exit ehci_hcd_pci_cleanup (void) | ||
412 | { | ||
413 | pci_unregister_driver (&ehci_pci_driver); | ||
414 | } | ||
415 | module_exit (ehci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f34a0516d35f..18e257c2bdb5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -97,6 +97,7 @@ struct ehci_hcd { /* one per controller */ | |||
97 | #else | 97 | #else |
98 | # define COUNT(x) do {} while (0) | 98 | # define COUNT(x) do {} while (0) |
99 | #endif | 99 | #endif |
100 | u8 sbrn; /* packed release number */ | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 103 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 642f35068ce2..ddb8fc591466 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -638,7 +638,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
638 | + msecs_to_jiffies(20) + 1); | 638 | + msecs_to_jiffies(20) + 1); |
639 | if (intstat & HCINT_RD) { | 639 | if (intstat & HCINT_RD) { |
640 | DBG("---- remote wakeup\n"); | 640 | DBG("---- remote wakeup\n"); |
641 | schedule_work(&isp116x->rh_resume); | 641 | usb_hcd_resume_root_hub(hcd); |
642 | ret = IRQ_HANDLED; | 642 | ret = IRQ_HANDLED; |
643 | } | 643 | } |
644 | irqstat &= ~HCuPINT_OPR; | 644 | irqstat &= ~HCuPINT_OPR; |
@@ -1160,7 +1160,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1160 | 1160 | ||
1161 | #ifdef CONFIG_PM | 1161 | #ifdef CONFIG_PM |
1162 | 1162 | ||
1163 | static int isp116x_hub_suspend(struct usb_hcd *hcd) | 1163 | static int isp116x_bus_suspend(struct usb_hcd *hcd) |
1164 | { | 1164 | { |
1165 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1165 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1166 | unsigned long flags; | 1166 | unsigned long flags; |
@@ -1200,7 +1200,7 @@ static int isp116x_hub_suspend(struct usb_hcd *hcd) | |||
1200 | return ret; | 1200 | return ret; |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | static int isp116x_hub_resume(struct usb_hcd *hcd) | 1203 | static int isp116x_bus_resume(struct usb_hcd *hcd) |
1204 | { | 1204 | { |
1205 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1205 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1206 | u32 val; | 1206 | u32 val; |
@@ -1263,21 +1263,11 @@ static int isp116x_hub_resume(struct usb_hcd *hcd) | |||
1263 | return 0; | 1263 | return 0; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | static void isp116x_rh_resume(void *_hcd) | ||
1267 | { | ||
1268 | struct usb_hcd *hcd = _hcd; | ||
1269 | |||
1270 | usb_resume_device(hcd->self.root_hub); | ||
1271 | } | ||
1272 | 1266 | ||
1273 | #else | 1267 | #else |
1274 | 1268 | ||
1275 | #define isp116x_hub_suspend NULL | 1269 | #define isp116x_bus_suspend NULL |
1276 | #define isp116x_hub_resume NULL | 1270 | #define isp116x_bus_resume NULL |
1277 | |||
1278 | static void isp116x_rh_resume(void *_hcd) | ||
1279 | { | ||
1280 | } | ||
1281 | 1271 | ||
1282 | #endif | 1272 | #endif |
1283 | 1273 | ||
@@ -1636,8 +1626,8 @@ static struct hc_driver isp116x_hc_driver = { | |||
1636 | 1626 | ||
1637 | .hub_status_data = isp116x_hub_status_data, | 1627 | .hub_status_data = isp116x_hub_status_data, |
1638 | .hub_control = isp116x_hub_control, | 1628 | .hub_control = isp116x_hub_control, |
1639 | .hub_suspend = isp116x_hub_suspend, | 1629 | .bus_suspend = isp116x_bus_suspend, |
1640 | .hub_resume = isp116x_hub_resume, | 1630 | .bus_resume = isp116x_bus_resume, |
1641 | }; | 1631 | }; |
1642 | 1632 | ||
1643 | /*----------------------------------------------------------------*/ | 1633 | /*----------------------------------------------------------------*/ |
@@ -1732,7 +1722,6 @@ static int __init isp116x_probe(struct device *dev) | |||
1732 | isp116x->addr_reg = addr_reg; | 1722 | isp116x->addr_reg = addr_reg; |
1733 | spin_lock_init(&isp116x->lock); | 1723 | spin_lock_init(&isp116x->lock); |
1734 | INIT_LIST_HEAD(&isp116x->async); | 1724 | INIT_LIST_HEAD(&isp116x->async); |
1735 | INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd); | ||
1736 | isp116x->board = dev->platform_data; | 1725 | isp116x->board = dev->platform_data; |
1737 | 1726 | ||
1738 | if (!isp116x->board) { | 1727 | if (!isp116x->board) { |
@@ -1777,16 +1766,10 @@ static int __init isp116x_probe(struct device *dev) | |||
1777 | static int isp116x_suspend(struct device *dev, pm_message_t state) | 1766 | static int isp116x_suspend(struct device *dev, pm_message_t state) |
1778 | { | 1767 | { |
1779 | int ret = 0; | 1768 | int ret = 0; |
1780 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1781 | 1769 | ||
1782 | VDBG("%s: state %x\n", __func__, state); | 1770 | VDBG("%s: state %x\n", __func__, state); |
1783 | 1771 | ||
1784 | ret = usb_suspend_device(hcd->self.root_hub, state); | 1772 | dev->power.power_state = state; |
1785 | if (!ret) { | ||
1786 | dev->power.power_state = state; | ||
1787 | INFO("%s suspended\n", hcd_name); | ||
1788 | } else | ||
1789 | ERR("%s suspend failed\n", hcd_name); | ||
1790 | 1773 | ||
1791 | return ret; | 1774 | return ret; |
1792 | } | 1775 | } |
@@ -1797,15 +1780,11 @@ static int isp116x_suspend(struct device *dev, pm_message_t state) | |||
1797 | static int isp116x_resume(struct device *dev) | 1780 | static int isp116x_resume(struct device *dev) |
1798 | { | 1781 | { |
1799 | int ret = 0; | 1782 | int ret = 0; |
1800 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1801 | 1783 | ||
1802 | VDBG("%s: state %x\n", __func__, dev->power.power_state); | 1784 | VDBG("%s: state %x\n", __func__, dev->power.power_state); |
1803 | 1785 | ||
1804 | ret = usb_resume_device(hcd->self.root_hub); | 1786 | dev->power.power_state = PMSG_ON; |
1805 | if (!ret) { | 1787 | |
1806 | dev->power.power_state = PMSG_ON; | ||
1807 | VDBG("%s resumed\n", (char *)hcd_name); | ||
1808 | } | ||
1809 | return ret; | 1788 | return ret; |
1810 | } | 1789 | } |
1811 | 1790 | ||
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index 58873470dcf5..c6fec96785fe 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -253,7 +253,6 @@ static const int cc_to_error[16] = { | |||
253 | 253 | ||
254 | struct isp116x { | 254 | struct isp116x { |
255 | spinlock_t lock; | 255 | spinlock_t lock; |
256 | struct work_struct rh_resume; | ||
257 | 256 | ||
258 | void __iomem *addr_reg; | 257 | void __iomem *addr_reg; |
259 | void __iomem *data_reg; | 258 | void __iomem *data_reg; |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 3981bf15c8c7..a277e258eb6c 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -214,6 +214,11 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
214 | */ | 214 | */ |
215 | .hub_status_data = ohci_hub_status_data, | 215 | .hub_status_data = ohci_hub_status_data, |
216 | .hub_control = ohci_hub_control, | 216 | .hub_control = ohci_hub_control, |
217 | #ifdef CONFIG_PM | ||
218 | .bus_suspend = ohci_bus_suspend, | ||
219 | .bus_resume = ohci_bus_resume, | ||
220 | #endif | ||
221 | .start_port_reset = ohci_start_port_reset, | ||
217 | }; | 222 | }; |
218 | 223 | ||
219 | /*-------------------------------------------------------------------------*/ | 224 | /*-------------------------------------------------------------------------*/ |
@@ -259,6 +264,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | |||
259 | 264 | ||
260 | static struct device_driver ohci_hcd_au1xxx_driver = { | 265 | static struct device_driver ohci_hcd_au1xxx_driver = { |
261 | .name = "au1xxx-ohci", | 266 | .name = "au1xxx-ohci", |
267 | .owner = THIS_MODULE, | ||
262 | .bus = &platform_bus_type, | 268 | .bus = &platform_bus_type, |
263 | .probe = ohci_hcd_au1xxx_drv_probe, | 269 | .probe = ohci_hcd_au1xxx_drv_probe, |
264 | .remove = ohci_hcd_au1xxx_drv_remove, | 270 | .remove = ohci_hcd_au1xxx_drv_remove, |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 7924c74f958e..7bfffcbbd226 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
193 | 193 | ||
194 | maybe_print_eds (controller, "donehead", | 194 | maybe_print_eds (controller, "donehead", |
195 | ohci_readl (controller, ®s->donehead), next, size); | 195 | ohci_readl (controller, ®s->donehead), next, size); |
196 | |||
197 | /* broken fminterval means traffic won't flow! */ | ||
198 | ohci_dbg (controller, "fminterval %08x\n", | ||
199 | ohci_readl (controller, ®s->fminterval)); | ||
200 | } | 196 | } |
201 | 197 | ||
202 | #define dbg_port_sw(hc,num,value,next,size) \ | 198 | #define dbg_port_sw(hc,num,value,next,size) \ |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index f8da8c7af7c6..5c0c6c8a7a82 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -723,7 +723,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
723 | ohci_vdbg (ohci, "resume detect\n"); | 723 | ohci_vdbg (ohci, "resume detect\n"); |
724 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); | 724 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); |
725 | if (hcd->state != HC_STATE_QUIESCING) | 725 | if (hcd->state != HC_STATE_QUIESCING) |
726 | schedule_work(&ohci->rh_resume); | 726 | usb_hcd_resume_root_hub(hcd); |
727 | } | 727 | } |
728 | 728 | ||
729 | if (ints & OHCI_INTR_WDH) { | 729 | if (ints & OHCI_INTR_WDH) { |
@@ -791,7 +791,7 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
791 | 791 | ||
792 | /* must not be called from interrupt context */ | 792 | /* must not be called from interrupt context */ |
793 | 793 | ||
794 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 794 | #ifdef CONFIG_PM |
795 | 795 | ||
796 | static int ohci_restart (struct ohci_hcd *ohci) | 796 | static int ohci_restart (struct ohci_hcd *ohci) |
797 | { | 797 | { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ce7b28da7a15..e01e77bc324b 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
38 | 38 | ||
39 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 39 | #ifdef CONFIG_PM |
40 | 40 | ||
41 | #define OHCI_SCHED_ENABLES \ | 41 | #define OHCI_SCHED_ENABLES \ |
42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) | 42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) |
@@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hcd *, struct pt_regs *); | |||
45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); | 45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); |
46 | static int ohci_restart (struct ohci_hcd *ohci); | 46 | static int ohci_restart (struct ohci_hcd *ohci); |
47 | 47 | ||
48 | static int ohci_hub_suspend (struct usb_hcd *hcd) | 48 | static int ohci_bus_suspend (struct usb_hcd *hcd) |
49 | { | 49 | { |
50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
51 | int status = 0; | 51 | int status = 0; |
@@ -73,7 +73,6 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
73 | ohci_dbg (ohci, "suspend root hub\n"); | 73 | ohci_dbg (ohci, "suspend root hub\n"); |
74 | 74 | ||
75 | /* First stop any processing */ | 75 | /* First stop any processing */ |
76 | hcd->state = HC_STATE_QUIESCING; | ||
77 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { | 76 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { |
78 | int limit; | 77 | int limit; |
79 | 78 | ||
@@ -108,7 +107,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
108 | else | 107 | else |
109 | ohci->hc_control &= ~OHCI_CTRL_RWE; | 108 | ohci->hc_control &= ~OHCI_CTRL_RWE; |
110 | 109 | ||
111 | /* Suspend hub */ | 110 | /* Suspend hub ... this is the "global (to this bus) suspend" mode, |
111 | * which doesn't imply ports will first be individually suspended. | ||
112 | */ | ||
112 | ohci->hc_control &= ~OHCI_CTRL_HCFS; | 113 | ohci->hc_control &= ~OHCI_CTRL_HCFS; |
113 | ohci->hc_control |= OHCI_USB_SUSPEND; | 114 | ohci->hc_control |= OHCI_USB_SUSPEND; |
114 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 115 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
@@ -118,8 +119,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
118 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); | 119 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); |
119 | 120 | ||
120 | done: | 121 | done: |
122 | /* external suspend vs self autosuspend ... same effect */ | ||
121 | if (status == 0) | 123 | if (status == 0) |
122 | hcd->state = HC_STATE_SUSPENDED; | 124 | usb_hcd_suspend_root_hub(hcd); |
123 | spin_unlock_irqrestore (&ohci->lock, flags); | 125 | spin_unlock_irqrestore (&ohci->lock, flags); |
124 | return status; | 126 | return status; |
125 | } | 127 | } |
@@ -133,7 +135,7 @@ static inline struct ed *find_head (struct ed *ed) | |||
133 | } | 135 | } |
134 | 136 | ||
135 | /* caller has locked the root hub */ | 137 | /* caller has locked the root hub */ |
136 | static int ohci_hub_resume (struct usb_hcd *hcd) | 138 | static int ohci_bus_resume (struct usb_hcd *hcd) |
137 | { | 139 | { |
138 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 140 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
139 | u32 temp, enables; | 141 | u32 temp, enables; |
@@ -146,7 +148,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
146 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 148 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
147 | 149 | ||
148 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | 150 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { |
149 | /* this can happen after suspend-to-disk */ | 151 | /* this can happen after resuming a swsusp snapshot */ |
150 | if (hcd->state == HC_STATE_RESUMING) { | 152 | if (hcd->state == HC_STATE_RESUMING) { |
151 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", | 153 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", |
152 | ohci->hc_control); | 154 | ohci->hc_control); |
@@ -169,11 +171,12 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
169 | ohci_info (ohci, "wakeup\n"); | 171 | ohci_info (ohci, "wakeup\n"); |
170 | break; | 172 | break; |
171 | case OHCI_USB_OPER: | 173 | case OHCI_USB_OPER: |
172 | ohci_dbg (ohci, "already resumed\n"); | 174 | /* this can happen after resuming a swsusp snapshot */ |
173 | status = 0; | 175 | ohci_dbg (ohci, "snapshot resume? reinit\n"); |
176 | status = -EBUSY; | ||
174 | break; | 177 | break; |
175 | default: /* RESET, we lost power */ | 178 | default: /* RESET, we lost power */ |
176 | ohci_dbg (ohci, "root hub hardware reset\n"); | 179 | ohci_dbg (ohci, "lost power\n"); |
177 | status = -EBUSY; | 180 | status = -EBUSY; |
178 | } | 181 | } |
179 | spin_unlock_irq (&ohci->lock); | 182 | spin_unlock_irq (&ohci->lock); |
@@ -198,8 +201,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
198 | } | 201 | } |
199 | 202 | ||
200 | /* Some controllers (lucent erratum) need extra-long delays */ | 203 | /* Some controllers (lucent erratum) need extra-long delays */ |
201 | hcd->state = HC_STATE_RESUMING; | 204 | msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); |
202 | mdelay (20 /* usb 11.5.1.10 */ + 15); | ||
203 | 205 | ||
204 | temp = ohci_readl (ohci, &ohci->regs->control); | 206 | temp = ohci_readl (ohci, &ohci->regs->control); |
205 | temp &= OHCI_CTRL_HCFS; | 207 | temp &= OHCI_CTRL_HCFS; |
@@ -273,28 +275,10 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
273 | (void) ohci_readl (ohci, &ohci->regs->control); | 275 | (void) ohci_readl (ohci, &ohci->regs->control); |
274 | } | 276 | } |
275 | 277 | ||
276 | hcd->state = HC_STATE_RUNNING; | ||
277 | return 0; | 278 | return 0; |
278 | } | 279 | } |
279 | 280 | ||
280 | static void ohci_rh_resume (void *_hcd) | 281 | #endif /* CONFIG_PM */ |
281 | { | ||
282 | struct usb_hcd *hcd = _hcd; | ||
283 | |||
284 | usb_lock_device (hcd->self.root_hub); | ||
285 | (void) ohci_hub_resume (hcd); | ||
286 | usb_unlock_device (hcd->self.root_hub); | ||
287 | } | ||
288 | |||
289 | #else | ||
290 | |||
291 | static void ohci_rh_resume (void *_hcd) | ||
292 | { | ||
293 | struct ohci_hcd *ohci = hcd_to_ohci (_hcd); | ||
294 | ohci_dbg(ohci, "rh_resume ??\n"); | ||
295 | } | ||
296 | |||
297 | #endif /* CONFIG_USB_SUSPEND || CONFIG_PM */ | ||
298 | 282 | ||
299 | /*-------------------------------------------------------------------------*/ | 283 | /*-------------------------------------------------------------------------*/ |
300 | 284 | ||
@@ -367,7 +351,6 @@ done: | |||
367 | #ifdef CONFIG_PM | 351 | #ifdef CONFIG_PM |
368 | /* save power by suspending idle root hubs; | 352 | /* save power by suspending idle root hubs; |
369 | * INTR_RD wakes us when there's work | 353 | * INTR_RD wakes us when there's work |
370 | * NOTE: if we can do this, we don't need a root hub timer! | ||
371 | */ | 354 | */ |
372 | if (can_suspend | 355 | if (can_suspend |
373 | && !changed | 356 | && !changed |
@@ -379,8 +362,7 @@ done: | |||
379 | && usb_trylock_device (hcd->self.root_hub) | 362 | && usb_trylock_device (hcd->self.root_hub) |
380 | ) { | 363 | ) { |
381 | ohci_vdbg (ohci, "autosuspend\n"); | 364 | ohci_vdbg (ohci, "autosuspend\n"); |
382 | (void) ohci_hub_suspend (hcd); | 365 | (void) ohci_bus_suspend (hcd); |
383 | hcd->state = HC_STATE_RUNNING; | ||
384 | usb_unlock_device (hcd->self.root_hub); | 366 | usb_unlock_device (hcd->self.root_hub); |
385 | } | 367 | } |
386 | #endif | 368 | #endif |
@@ -554,7 +536,7 @@ static int ohci_hub_control ( | |||
554 | temp = RH_PS_POCI; | 536 | temp = RH_PS_POCI; |
555 | if ((ohci->hc_control & OHCI_CTRL_HCFS) | 537 | if ((ohci->hc_control & OHCI_CTRL_HCFS) |
556 | != OHCI_USB_OPER) | 538 | != OHCI_USB_OPER) |
557 | schedule_work (&ohci->rh_resume); | 539 | usb_hcd_resume_root_hub(hcd); |
558 | break; | 540 | break; |
559 | case USB_PORT_FEAT_C_SUSPEND: | 541 | case USB_PORT_FEAT_C_SUSPEND: |
560 | temp = RH_PS_PSSC; | 542 | temp = RH_PS_PSSC; |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 859aca7be753..238fa4ade615 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -193,6 +193,11 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
193 | */ | 193 | */ |
194 | .hub_status_data = ohci_hub_status_data, | 194 | .hub_status_data = ohci_hub_status_data, |
195 | .hub_control = ohci_hub_control, | 195 | .hub_control = ohci_hub_control, |
196 | #ifdef CONFIG_PM | ||
197 | .bus_suspend = ohci_bus_suspend, | ||
198 | .bus_resume = ohci_bus_resume, | ||
199 | #endif | ||
200 | .start_port_reset = ohci_start_port_reset, | ||
196 | }; | 201 | }; |
197 | 202 | ||
198 | /*-------------------------------------------------------------------------*/ | 203 | /*-------------------------------------------------------------------------*/ |
@@ -239,6 +244,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct device *dev) | |||
239 | 244 | ||
240 | static struct device_driver ohci_hcd_lh7a404_driver = { | 245 | static struct device_driver ohci_hcd_lh7a404_driver = { |
241 | .name = "lh7a404-ohci", | 246 | .name = "lh7a404-ohci", |
247 | .owner = THIS_MODULE, | ||
242 | .bus = &platform_bus_type, | 248 | .bus = &platform_bus_type, |
243 | .probe = ohci_hcd_lh7a404_drv_probe, | 249 | .probe = ohci_hcd_lh7a404_drv_probe, |
244 | .remove = ohci_hcd_lh7a404_drv_remove, | 250 | .remove = ohci_hcd_lh7a404_drv_remove, |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 9fb83dfb1eb4..bfbe328a4788 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); | ||
32 | ohci->reboot_notifier.notifier_call = ohci_reboot; | 31 | ohci->reboot_notifier.notifier_call = ohci_reboot; |
33 | } | 32 | } |
34 | 33 | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a574216625a0..45efeed1fcc3 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -420,9 +420,9 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
420 | */ | 420 | */ |
421 | .hub_status_data = ohci_hub_status_data, | 421 | .hub_status_data = ohci_hub_status_data, |
422 | .hub_control = ohci_hub_control, | 422 | .hub_control = ohci_hub_control, |
423 | #ifdef CONFIG_USB_SUSPEND | 423 | #ifdef CONFIG_PM |
424 | .hub_suspend = ohci_hub_suspend, | 424 | .bus_suspend = ohci_bus_suspend, |
425 | .hub_resume = ohci_hub_resume, | 425 | .bus_resume = ohci_bus_resume, |
426 | #endif | 426 | #endif |
427 | .start_port_reset = ohci_start_port_reset, | 427 | .start_port_reset = ohci_start_port_reset, |
428 | }; | 428 | }; |
@@ -458,41 +458,29 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) | |||
458 | static int ohci_omap_suspend(struct device *dev, pm_message_t message) | 458 | static int ohci_omap_suspend(struct device *dev, pm_message_t message) |
459 | { | 459 | { |
460 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 460 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
461 | int status = -EINVAL; | 461 | |
462 | 462 | if (time_before(jiffies, ohci->next_statechange)) | |
463 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 463 | msleep(5); |
464 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); | 464 | ohci->next_statechange = jiffies; |
465 | if (status == 0) { | 465 | |
466 | omap_ohci_clock_power(0); | 466 | omap_ohci_clock_power(0); |
467 | ohci_to_hcd(ohci)->self.root_hub->state = | 467 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; |
468 | USB_STATE_SUSPENDED; | 468 | dev->power.power_state = PMSG_SUSPEND; |
469 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | 469 | return 0; |
470 | dev->power.power_state = PMSG_SUSPEND; | ||
471 | } | ||
472 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
473 | return status; | ||
474 | } | 470 | } |
475 | 471 | ||
476 | static int ohci_omap_resume(struct device *dev) | 472 | static int ohci_omap_resume(struct device *dev) |
477 | { | 473 | { |
478 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 474 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
479 | int status = 0; | ||
480 | 475 | ||
481 | if (time_before(jiffies, ohci->next_statechange)) | 476 | if (time_before(jiffies, ohci->next_statechange)) |
482 | msleep(5); | 477 | msleep(5); |
483 | ohci->next_statechange = jiffies; | 478 | ohci->next_statechange = jiffies; |
479 | |||
484 | omap_ohci_clock_power(1); | 480 | omap_ohci_clock_power(1); |
485 | #ifdef CONFIG_USB_SUSPEND | 481 | dev->power.power_state = PMSG_ON; |
486 | /* get extra cleanup even if remote wakeup isn't in use */ | 482 | usb_hcd_resume_root_hub(dev_get_drvdata(dev)); |
487 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); | 483 | return 0; |
488 | #else | ||
489 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
490 | status = ohci_hub_resume(ohci_to_hcd(ohci)); | ||
491 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
492 | #endif | ||
493 | if (status == 0) | ||
494 | dev->power.power_state = PMSG_ON; | ||
495 | return status; | ||
496 | } | 484 | } |
497 | 485 | ||
498 | #endif | 486 | #endif |
@@ -504,6 +492,7 @@ static int ohci_omap_resume(struct device *dev) | |||
504 | */ | 492 | */ |
505 | static struct device_driver ohci_hcd_omap_driver = { | 493 | static struct device_driver ohci_hcd_omap_driver = { |
506 | .name = "ohci", | 494 | .name = "ohci", |
495 | .owner = THIS_MODULE, | ||
507 | .bus = &platform_bus_type, | 496 | .bus = &platform_bus_type, |
508 | .probe = ohci_hcd_omap_drv_probe, | 497 | .probe = ohci_hcd_omap_drv_probe, |
509 | .remove = ohci_hcd_omap_drv_remove, | 498 | .remove = ohci_hcd_omap_drv_remove, |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index eede6be098d2..bf1d5ab4aa3a 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -112,23 +112,13 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
112 | 112 | ||
113 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | 113 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) |
114 | { | 114 | { |
115 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 115 | /* root hub was already suspended */ |
116 | |||
117 | /* suspend root hub, hoping it keeps power during suspend */ | ||
118 | if (time_before (jiffies, ohci->next_statechange)) | ||
119 | msleep (100); | ||
120 | |||
121 | #ifdef CONFIG_USB_SUSPEND | ||
122 | (void) usb_suspend_device (hcd->self.root_hub, message); | ||
123 | #else | ||
124 | usb_lock_device (hcd->self.root_hub); | ||
125 | (void) ohci_hub_suspend (hcd); | ||
126 | usb_unlock_device (hcd->self.root_hub); | ||
127 | #endif | ||
128 | 116 | ||
129 | /* let things settle down a bit */ | 117 | /* FIXME these PMAC things get called in the wrong places. ASIC |
130 | msleep (100); | 118 | * clocks should be turned off AFTER entering D3, and on BEFORE |
131 | 119 | * trying to enter D0. Evidently the PCI layer doesn't currently | |
120 | * provide the right sort of platform hooks for this ... | ||
121 | */ | ||
132 | #ifdef CONFIG_PPC_PMAC | 122 | #ifdef CONFIG_PPC_PMAC |
133 | if (_machine == _MACH_Pmac) { | 123 | if (_machine == _MACH_Pmac) { |
134 | struct device_node *of_node; | 124 | struct device_node *of_node; |
@@ -145,9 +135,6 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | |||
145 | 135 | ||
146 | static int ohci_pci_resume (struct usb_hcd *hcd) | 136 | static int ohci_pci_resume (struct usb_hcd *hcd) |
147 | { | 137 | { |
148 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
149 | int retval = 0; | ||
150 | |||
151 | #ifdef CONFIG_PPC_PMAC | 138 | #ifdef CONFIG_PPC_PMAC |
152 | if (_machine == _MACH_Pmac) { | 139 | if (_machine == _MACH_Pmac) { |
153 | struct device_node *of_node; | 140 | struct device_node *of_node; |
@@ -159,19 +146,8 @@ static int ohci_pci_resume (struct usb_hcd *hcd) | |||
159 | } | 146 | } |
160 | #endif /* CONFIG_PPC_PMAC */ | 147 | #endif /* CONFIG_PPC_PMAC */ |
161 | 148 | ||
162 | /* resume root hub */ | 149 | usb_hcd_resume_root_hub(hcd); |
163 | if (time_before (jiffies, ohci->next_statechange)) | 150 | return 0; |
164 | msleep (100); | ||
165 | #ifdef CONFIG_USB_SUSPEND | ||
166 | /* get extra cleanup even if remote wakeup isn't in use */ | ||
167 | retval = usb_resume_device (hcd->self.root_hub); | ||
168 | #else | ||
169 | usb_lock_device (hcd->self.root_hub); | ||
170 | retval = ohci_hub_resume (hcd); | ||
171 | usb_unlock_device (hcd->self.root_hub); | ||
172 | #endif | ||
173 | |||
174 | return retval; | ||
175 | } | 151 | } |
176 | 152 | ||
177 | #endif /* CONFIG_PM */ | 153 | #endif /* CONFIG_PM */ |
@@ -218,9 +194,9 @@ static const struct hc_driver ohci_pci_hc_driver = { | |||
218 | */ | 194 | */ |
219 | .hub_status_data = ohci_hub_status_data, | 195 | .hub_status_data = ohci_hub_status_data, |
220 | .hub_control = ohci_hub_control, | 196 | .hub_control = ohci_hub_control, |
221 | #ifdef CONFIG_USB_SUSPEND | 197 | #ifdef CONFIG_PM |
222 | .hub_suspend = ohci_hub_suspend, | 198 | .bus_suspend = ohci_bus_suspend, |
223 | .hub_resume = ohci_hub_resume, | 199 | .bus_resume = ohci_bus_resume, |
224 | #endif | 200 | #endif |
225 | .start_port_reset = ohci_start_port_reset, | 201 | .start_port_reset = ohci_start_port_reset, |
226 | }; | 202 | }; |
@@ -240,6 +216,7 @@ MODULE_DEVICE_TABLE (pci, pci_ids); | |||
240 | static struct pci_driver ohci_pci_driver = { | 216 | static struct pci_driver ohci_pci_driver = { |
241 | .name = (char *) hcd_name, | 217 | .name = (char *) hcd_name, |
242 | .id_table = pci_ids, | 218 | .id_table = pci_ids, |
219 | .owner = THIS_MODULE, | ||
243 | 220 | ||
244 | .probe = usb_hcd_pci_probe, | 221 | .probe = usb_hcd_pci_probe, |
245 | .remove = usb_hcd_pci_remove, | 222 | .remove = usb_hcd_pci_remove, |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 251533363028..4832e57ae579 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -163,9 +163,9 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
163 | */ | 163 | */ |
164 | .hub_status_data = ohci_hub_status_data, | 164 | .hub_status_data = ohci_hub_status_data, |
165 | .hub_control = ohci_hub_control, | 165 | .hub_control = ohci_hub_control, |
166 | #ifdef CONFIG_USB_SUSPEND | 166 | #ifdef CONFIG_PM |
167 | .hub_suspend = ohci_hub_suspend, | 167 | .bus_suspend = ohci_bus_suspend, |
168 | .hub_resume = ohci_hub_resume, | 168 | .bus_resume = ohci_bus_resume, |
169 | #endif | 169 | #endif |
170 | .start_port_reset = ohci_start_port_reset, | 170 | .start_port_reset = ohci_start_port_reset, |
171 | }; | 171 | }; |
@@ -193,10 +193,11 @@ static int ohci_hcd_ppc_soc_drv_remove(struct device *dev) | |||
193 | 193 | ||
194 | static struct device_driver ohci_hcd_ppc_soc_driver = { | 194 | static struct device_driver ohci_hcd_ppc_soc_driver = { |
195 | .name = "ppc-soc-ohci", | 195 | .name = "ppc-soc-ohci", |
196 | .owner = THIS_MODULE, | ||
196 | .bus = &platform_bus_type, | 197 | .bus = &platform_bus_type, |
197 | .probe = ohci_hcd_ppc_soc_drv_probe, | 198 | .probe = ohci_hcd_ppc_soc_drv_probe, |
198 | .remove = ohci_hcd_ppc_soc_drv_remove, | 199 | .remove = ohci_hcd_ppc_soc_drv_remove, |
199 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 200 | #ifdef CONFIG_PM |
200 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | 201 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ |
201 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | 202 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ |
202 | #endif | 203 | #endif |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index f042261ecb8e..d287dcccd415 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -278,10 +278,11 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
278 | */ | 278 | */ |
279 | .hub_status_data = ohci_hub_status_data, | 279 | .hub_status_data = ohci_hub_status_data, |
280 | .hub_control = ohci_hub_control, | 280 | .hub_control = ohci_hub_control, |
281 | #ifdef CONFIG_USB_SUSPEND | 281 | #ifdef CONFIG_PM |
282 | .hub_suspend = ohci_hub_suspend, | 282 | .bus_suspend = ohci_bus_suspend, |
283 | .hub_resume = ohci_hub_resume, | 283 | .bus_resume = ohci_bus_resume, |
284 | #endif | 284 | #endif |
285 | .start_port_reset = ohci_start_port_reset, | ||
285 | }; | 286 | }; |
286 | 287 | ||
287 | /*-------------------------------------------------------------------------*/ | 288 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index da7d5478f74d..fab420a2ce71 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -448,11 +448,11 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
448 | */ | 448 | */ |
449 | .hub_status_data = ohci_s3c2410_hub_status_data, | 449 | .hub_status_data = ohci_s3c2410_hub_status_data, |
450 | .hub_control = ohci_s3c2410_hub_control, | 450 | .hub_control = ohci_s3c2410_hub_control, |
451 | 451 | #ifdef CONFIG_PM | |
452 | #if defined(CONFIG_USB_SUSPEND) && 0 | 452 | .bus_suspend = ohci_bus_suspend, |
453 | .hub_suspend = ohci_hub_suspend, | 453 | .bus_resume = ohci_bus_resume, |
454 | .hub_resume = ohci_hub_resume, | ||
455 | #endif | 454 | #endif |
455 | .start_port_reset = ohci_start_port_reset, | ||
456 | }; | 456 | }; |
457 | 457 | ||
458 | /* device driver */ | 458 | /* device driver */ |
@@ -474,6 +474,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct device *dev) | |||
474 | 474 | ||
475 | static struct device_driver ohci_hcd_s3c2410_driver = { | 475 | static struct device_driver ohci_hcd_s3c2410_driver = { |
476 | .name = "s3c2410-ohci", | 476 | .name = "s3c2410-ohci", |
477 | .owner = THIS_MODULE, | ||
477 | .bus = &platform_bus_type, | 478 | .bus = &platform_bus_type, |
478 | .probe = ohci_hcd_s3c2410_drv_probe, | 479 | .probe = ohci_hcd_s3c2410_drv_probe, |
479 | .remove = ohci_hcd_s3c2410_drv_remove, | 480 | .remove = ohci_hcd_s3c2410_drv_remove, |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 814d2be4ee7b..fb3221ebbb29 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -235,10 +235,11 @@ static const struct hc_driver ohci_sa1111_hc_driver = { | |||
235 | */ | 235 | */ |
236 | .hub_status_data = ohci_hub_status_data, | 236 | .hub_status_data = ohci_hub_status_data, |
237 | .hub_control = ohci_hub_control, | 237 | .hub_control = ohci_hub_control, |
238 | #ifdef CONFIG_USB_SUSPEND | 238 | #ifdef CONFIG_PM |
239 | .hub_suspend = ohci_hub_suspend, | 239 | .bus_suspend = ohci_bus_suspend, |
240 | .hub_resume = ohci_hub_resume, | 240 | .bus_resume = ohci_bus_resume, |
241 | #endif | 241 | #endif |
242 | .start_port_reset = ohci_start_port_reset, | ||
242 | }; | 243 | }; |
243 | 244 | ||
244 | /*-------------------------------------------------------------------------*/ | 245 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 8a9b9d9209e9..caacf14371f5 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -389,7 +389,6 @@ struct ohci_hcd { | |||
389 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | 391 | ||
392 | struct work_struct rh_resume; | ||
393 | struct notifier_block reboot_notifier; | 392 | struct notifier_block reboot_notifier; |
394 | 393 | ||
395 | unsigned long flags; /* for HC bugs */ | 394 | unsigned long flags; /* for HC bugs */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c new file mode 100644 index 000000000000..b7fd3f644e1e --- /dev/null +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | * This file contains code to reset and initialize USB host controllers. | ||
3 | * Some of it includes work-arounds for PCI hardware and BIOS quirks. | ||
4 | * It may need to run early during booting -- before USB would normally | ||
5 | * initialize -- to ensure that Linux doesn't use any legacy modes. | ||
6 | * | ||
7 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | ||
8 | * (and others) | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/acpi.h> | ||
24 | |||
25 | |||
26 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | ||
27 | #define UHCI_USBCMD 0 /* command register */ | ||
28 | #define UHCI_USBINTR 4 /* interrupt register */ | ||
29 | #define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | ||
30 | #define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | ||
31 | #define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */ | ||
32 | #define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */ | ||
33 | #define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */ | ||
34 | #define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */ | ||
35 | #define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */ | ||
36 | |||
37 | #define OHCI_CONTROL 0x04 | ||
38 | #define OHCI_CMDSTATUS 0x08 | ||
39 | #define OHCI_INTRSTATUS 0x0c | ||
40 | #define OHCI_INTRENABLE 0x10 | ||
41 | #define OHCI_INTRDISABLE 0x14 | ||
42 | #define OHCI_OCR (1 << 3) /* ownership change request */ | ||
43 | #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ | ||
44 | #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ | ||
45 | #define OHCI_INTR_OC (1 << 30) /* ownership change */ | ||
46 | |||
47 | #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ | ||
48 | #define EHCI_USBCMD 0 /* command register */ | ||
49 | #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
50 | #define EHCI_USBSTS 4 /* status register */ | ||
51 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | ||
52 | #define EHCI_USBINTR 8 /* interrupt register */ | ||
53 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | ||
54 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | ||
55 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | ||
56 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | ||
57 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | ||
58 | |||
59 | |||
60 | /* | ||
61 | * Make sure the controller is completely inactive, unable to | ||
62 | * generate interrupts or do DMA. | ||
63 | */ | ||
64 | void uhci_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
65 | { | ||
66 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
67 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
68 | */ | ||
69 | pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC); | ||
70 | |||
71 | /* Reset the HC - this will force us to get a | ||
72 | * new notification of any already connected | ||
73 | * ports due to the virtual disconnect that it | ||
74 | * implies. | ||
75 | */ | ||
76 | outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); | ||
77 | mb(); | ||
78 | udelay(5); | ||
79 | if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET) | ||
80 | dev_warn(&pdev->dev, "HCRESET not completed yet!\n"); | ||
81 | |||
82 | /* Just to be safe, disable interrupt requests and | ||
83 | * make sure the controller is stopped. | ||
84 | */ | ||
85 | outw(0, base + UHCI_USBINTR); | ||
86 | outw(0, base + UHCI_USBCMD); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(uhci_reset_hc); | ||
89 | |||
90 | /* | ||
91 | * Initialize a controller that was newly discovered or has just been | ||
92 | * resumed. In either case we can't be sure of its previous state. | ||
93 | * | ||
94 | * Returns: 1 if the controller was reset, 0 otherwise. | ||
95 | */ | ||
96 | int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
97 | { | ||
98 | u16 legsup; | ||
99 | unsigned int cmd, intr; | ||
100 | |||
101 | /* | ||
102 | * When restarting a suspended controller, we expect all the | ||
103 | * settings to be the same as we left them: | ||
104 | * | ||
105 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
106 | * Controller is stopped and configured with EGSM set; | ||
107 | * No interrupts enabled except possibly Resume Detect. | ||
108 | * | ||
109 | * If any of these conditions are violated we do a complete reset. | ||
110 | */ | ||
111 | pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); | ||
112 | if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { | ||
113 | dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", | ||
114 | __FUNCTION__, legsup); | ||
115 | goto reset_needed; | ||
116 | } | ||
117 | |||
118 | cmd = inw(base + UHCI_USBCMD); | ||
119 | if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || | ||
120 | !(cmd & UHCI_USBCMD_EGSM)) { | ||
121 | dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", | ||
122 | __FUNCTION__, cmd); | ||
123 | goto reset_needed; | ||
124 | } | ||
125 | |||
126 | intr = inw(base + UHCI_USBINTR); | ||
127 | if (intr & (~UHCI_USBINTR_RESUME)) { | ||
128 | dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", | ||
129 | __FUNCTION__, intr); | ||
130 | goto reset_needed; | ||
131 | } | ||
132 | return 0; | ||
133 | |||
134 | reset_needed: | ||
135 | dev_dbg(&pdev->dev, "Performing full reset\n"); | ||
136 | uhci_reset_hc(pdev, base); | ||
137 | return 1; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); | ||
140 | |||
141 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | ||
142 | { | ||
143 | unsigned long base = 0; | ||
144 | int i; | ||
145 | |||
146 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
147 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | ||
148 | base = pci_resource_start(pdev, i); | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | if (base) | ||
153 | uhci_check_and_reset_hc(pdev, base); | ||
154 | } | ||
155 | |||
156 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||
157 | { | ||
158 | void __iomem *base; | ||
159 | int wait_time; | ||
160 | u32 control; | ||
161 | |||
162 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
163 | pci_resource_len(pdev, 0)); | ||
164 | if (base == NULL) return; | ||
165 | |||
166 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | ||
167 | #ifndef __hppa__ | ||
168 | control = readl(base + OHCI_CONTROL); | ||
169 | if (control & OHCI_CTRL_IR) { | ||
170 | wait_time = 500; /* arbitrary; 5 seconds */ | ||
171 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | ||
172 | writel(OHCI_OCR, base + OHCI_CMDSTATUS); | ||
173 | while (wait_time > 0 && | ||
174 | readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
175 | wait_time -= 10; | ||
176 | msleep(10); | ||
177 | } | ||
178 | if (wait_time <= 0) | ||
179 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
180 | "failed (BIOS bug ?)\n", | ||
181 | pdev->dev.bus_id, "OHCI"); | ||
182 | |||
183 | /* reset controller, preserving RWC */ | ||
184 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | /* | ||
189 | * disable interrupts | ||
190 | */ | ||
191 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
192 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
193 | |||
194 | iounmap(base); | ||
195 | } | ||
196 | |||
197 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | ||
198 | { | ||
199 | int wait_time, delta; | ||
200 | void __iomem *base, *op_reg_base; | ||
201 | u32 hcc_params, val, temp; | ||
202 | u8 cap_length; | ||
203 | |||
204 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
205 | pci_resource_len(pdev, 0)); | ||
206 | if (base == NULL) return; | ||
207 | |||
208 | cap_length = readb(base); | ||
209 | op_reg_base = base + cap_length; | ||
210 | hcc_params = readl(base + EHCI_HCC_PARAMS); | ||
211 | hcc_params = (hcc_params >> 8) & 0xff; | ||
212 | if (hcc_params) { | ||
213 | pci_read_config_dword(pdev, | ||
214 | hcc_params + EHCI_USBLEGSUP, | ||
215 | &val); | ||
216 | if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { | ||
217 | /* | ||
218 | * Ok, BIOS is in smm mode, try to hand off... | ||
219 | */ | ||
220 | pci_read_config_dword(pdev, | ||
221 | hcc_params + EHCI_USBLEGCTLSTS, | ||
222 | &temp); | ||
223 | pci_write_config_dword(pdev, | ||
224 | hcc_params + EHCI_USBLEGCTLSTS, | ||
225 | temp | EHCI_USBLEGCTLSTS_SOOE); | ||
226 | val |= EHCI_USBLEGSUP_OS; | ||
227 | pci_write_config_dword(pdev, | ||
228 | hcc_params + EHCI_USBLEGSUP, | ||
229 | val); | ||
230 | |||
231 | wait_time = 500; | ||
232 | do { | ||
233 | msleep(10); | ||
234 | wait_time -= 10; | ||
235 | pci_read_config_dword(pdev, | ||
236 | hcc_params + EHCI_USBLEGSUP, | ||
237 | &val); | ||
238 | } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); | ||
239 | if (!wait_time) { | ||
240 | /* | ||
241 | * well, possibly buggy BIOS... | ||
242 | */ | ||
243 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
244 | "failed (BIOS bug ?)\n", | ||
245 | pdev->dev.bus_id, "EHCI"); | ||
246 | pci_write_config_dword(pdev, | ||
247 | hcc_params + EHCI_USBLEGSUP, | ||
248 | EHCI_USBLEGSUP_OS); | ||
249 | pci_write_config_dword(pdev, | ||
250 | hcc_params + EHCI_USBLEGCTLSTS, | ||
251 | 0); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * halt EHCI & disable its interrupts in any case | ||
258 | */ | ||
259 | val = readl(op_reg_base + EHCI_USBSTS); | ||
260 | if ((val & EHCI_USBSTS_HALTED) == 0) { | ||
261 | val = readl(op_reg_base + EHCI_USBCMD); | ||
262 | val &= ~EHCI_USBCMD_RUN; | ||
263 | writel(val, op_reg_base + EHCI_USBCMD); | ||
264 | |||
265 | wait_time = 2000; | ||
266 | delta = 100; | ||
267 | do { | ||
268 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
269 | udelay(delta); | ||
270 | wait_time -= delta; | ||
271 | val = readl(op_reg_base + EHCI_USBSTS); | ||
272 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | ||
273 | break; | ||
274 | } | ||
275 | } while (wait_time > 0); | ||
276 | } | ||
277 | writel(0, op_reg_base + EHCI_USBINTR); | ||
278 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
279 | |||
280 | iounmap(base); | ||
281 | |||
282 | return; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||
288 | { | ||
289 | if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) | ||
290 | quirk_usb_handoff_uhci(pdev); | ||
291 | else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) | ||
292 | quirk_usb_handoff_ohci(pdev); | ||
293 | else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
294 | quirk_usb_disable_ehci(pdev); | ||
295 | } | ||
296 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index b5e7a478bc01..40169d9cf2b1 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -1363,7 +1363,7 @@ error: | |||
1363 | #ifdef CONFIG_PM | 1363 | #ifdef CONFIG_PM |
1364 | 1364 | ||
1365 | static int | 1365 | static int |
1366 | sl811h_hub_suspend(struct usb_hcd *hcd) | 1366 | sl811h_bus_suspend(struct usb_hcd *hcd) |
1367 | { | 1367 | { |
1368 | // SOFs off | 1368 | // SOFs off |
1369 | DBG("%s\n", __FUNCTION__); | 1369 | DBG("%s\n", __FUNCTION__); |
@@ -1371,7 +1371,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd) | |||
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | static int | 1373 | static int |
1374 | sl811h_hub_resume(struct usb_hcd *hcd) | 1374 | sl811h_bus_resume(struct usb_hcd *hcd) |
1375 | { | 1375 | { |
1376 | // SOFs on | 1376 | // SOFs on |
1377 | DBG("%s\n", __FUNCTION__); | 1377 | DBG("%s\n", __FUNCTION__); |
@@ -1380,8 +1380,8 @@ sl811h_hub_resume(struct usb_hcd *hcd) | |||
1380 | 1380 | ||
1381 | #else | 1381 | #else |
1382 | 1382 | ||
1383 | #define sl811h_hub_suspend NULL | 1383 | #define sl811h_bus_suspend NULL |
1384 | #define sl811h_hub_resume NULL | 1384 | #define sl811h_bus_resume NULL |
1385 | 1385 | ||
1386 | #endif | 1386 | #endif |
1387 | 1387 | ||
@@ -1623,8 +1623,8 @@ static struct hc_driver sl811h_hc_driver = { | |||
1623 | */ | 1623 | */ |
1624 | .hub_status_data = sl811h_hub_status_data, | 1624 | .hub_status_data = sl811h_hub_status_data, |
1625 | .hub_control = sl811h_hub_control, | 1625 | .hub_control = sl811h_hub_control, |
1626 | .hub_suspend = sl811h_hub_suspend, | 1626 | .bus_suspend = sl811h_bus_suspend, |
1627 | .hub_resume = sl811h_hub_resume, | 1627 | .bus_resume = sl811h_bus_resume, |
1628 | }; | 1628 | }; |
1629 | 1629 | ||
1630 | /*-------------------------------------------------------------------------*/ | 1630 | /*-------------------------------------------------------------------------*/ |
@@ -1791,7 +1791,7 @@ sl811h_suspend(struct device *dev, pm_message_t state) | |||
1791 | int retval = 0; | 1791 | int retval = 0; |
1792 | 1792 | ||
1793 | if (state.event == PM_EVENT_FREEZE) | 1793 | if (state.event == PM_EVENT_FREEZE) |
1794 | retval = sl811h_hub_suspend(hcd); | 1794 | retval = sl811h_bus_suspend(hcd); |
1795 | else if (state.event == PM_EVENT_SUSPEND) | 1795 | else if (state.event == PM_EVENT_SUSPEND) |
1796 | port_power(sl811, 0); | 1796 | port_power(sl811, 0); |
1797 | if (retval == 0) | 1797 | if (retval == 0) |
@@ -1816,7 +1816,7 @@ sl811h_resume(struct device *dev) | |||
1816 | } | 1816 | } |
1817 | 1817 | ||
1818 | dev->power.power_state = PMSG_ON; | 1818 | dev->power.power_state = PMSG_ON; |
1819 | return sl811h_hub_resume(hcd); | 1819 | return sl811h_bus_resume(hcd); |
1820 | } | 1820 | } |
1821 | 1821 | ||
1822 | #else | 1822 | #else |
@@ -1831,6 +1831,7 @@ sl811h_resume(struct device *dev) | |||
1831 | struct device_driver sl811h_driver = { | 1831 | struct device_driver sl811h_driver = { |
1832 | .name = (char *) hcd_name, | 1832 | .name = (char *) hcd_name, |
1833 | .bus = &platform_bus_type, | 1833 | .bus = &platform_bus_type, |
1834 | .owner = THIS_MODULE, | ||
1834 | 1835 | ||
1835 | .probe = sl811h_probe, | 1836 | .probe = sl811h_probe, |
1836 | .remove = __devexit_p(sl811h_remove), | 1837 | .remove = __devexit_p(sl811h_remove), |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 4538a98b6f9d..151154df37fa 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *bu | |||
348 | 348 | ||
349 | if (urbp->urb->status != -EINPROGRESS) | 349 | if (urbp->urb->status != -EINPROGRESS) |
350 | out += sprintf(out, "Status=%d ", urbp->urb->status); | 350 | out += sprintf(out, "Status=%d ", urbp->urb->status); |
351 | //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime); | ||
352 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); | 351 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); |
353 | 352 | ||
354 | count = 0; | 353 | count = 0; |
@@ -446,11 +445,11 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
446 | out += sprintf(out, "Frame List\n"); | 445 | out += sprintf(out, "Frame List\n"); |
447 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 446 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
448 | int shown = 0; | 447 | int shown = 0; |
449 | td = uhci->fl->frame_cpu[i]; | 448 | td = uhci->frame_cpu[i]; |
450 | if (!td) | 449 | if (!td) |
451 | continue; | 450 | continue; |
452 | 451 | ||
453 | if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) { | 452 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) { |
454 | show_frame_num(); | 453 | show_frame_num(); |
455 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 454 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); |
456 | } | 455 | } |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 0c024898cbea..15e0a511069b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -101,37 +101,16 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
101 | #include "uhci-q.c" | 101 | #include "uhci-q.c" |
102 | #include "uhci-hub.c" | 102 | #include "uhci-hub.c" |
103 | 103 | ||
104 | extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
105 | extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
106 | |||
104 | /* | 107 | /* |
105 | * Make sure the controller is completely inactive, unable to | 108 | * Finish up a host controller reset and update the recorded state. |
106 | * generate interrupts or do DMA. | ||
107 | */ | 109 | */ |
108 | static void reset_hc(struct uhci_hcd *uhci) | 110 | static void finish_reset(struct uhci_hcd *uhci) |
109 | { | 111 | { |
110 | int port; | 112 | int port; |
111 | 113 | ||
112 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
113 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
114 | */ | ||
115 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, | ||
116 | USBLEGSUP_RWC); | ||
117 | |||
118 | /* Reset the HC - this will force us to get a | ||
119 | * new notification of any already connected | ||
120 | * ports due to the virtual disconnect that it | ||
121 | * implies. | ||
122 | */ | ||
123 | outw(USBCMD_HCRESET, uhci->io_addr + USBCMD); | ||
124 | mb(); | ||
125 | udelay(5); | ||
126 | if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET) | ||
127 | dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n"); | ||
128 | |||
129 | /* Just to be safe, disable interrupt requests and | ||
130 | * make sure the controller is stopped. | ||
131 | */ | ||
132 | outw(0, uhci->io_addr + USBINTR); | ||
133 | outw(0, uhci->io_addr + USBCMD); | ||
134 | |||
135 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect | 114 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect |
136 | * bits in the port status and control registers. | 115 | * bits in the port status and control registers. |
137 | * We have to clear them by hand. | 116 | * We have to clear them by hand. |
@@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uhci) | |||
153 | */ | 132 | */ |
154 | static void hc_died(struct uhci_hcd *uhci) | 133 | static void hc_died(struct uhci_hcd *uhci) |
155 | { | 134 | { |
156 | reset_hc(uhci); | 135 | uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); |
136 | finish_reset(uhci); | ||
157 | uhci->hc_inaccessible = 1; | 137 | uhci->hc_inaccessible = 1; |
158 | } | 138 | } |
159 | 139 | ||
@@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhci) | |||
163 | */ | 143 | */ |
164 | static void check_and_reset_hc(struct uhci_hcd *uhci) | 144 | static void check_and_reset_hc(struct uhci_hcd *uhci) |
165 | { | 145 | { |
166 | u16 legsup; | 146 | if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr)) |
167 | unsigned int cmd, intr; | 147 | finish_reset(uhci); |
168 | |||
169 | /* | ||
170 | * When restarting a suspended controller, we expect all the | ||
171 | * settings to be the same as we left them: | ||
172 | * | ||
173 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
174 | * Controller is stopped and configured with EGSM set; | ||
175 | * No interrupts enabled except possibly Resume Detect. | ||
176 | * | ||
177 | * If any of these conditions are violated we do a complete reset. | ||
178 | */ | ||
179 | pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); | ||
180 | if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { | ||
181 | dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", | ||
182 | __FUNCTION__, legsup); | ||
183 | goto reset_needed; | ||
184 | } | ||
185 | |||
186 | cmd = inw(uhci->io_addr + USBCMD); | ||
187 | if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { | ||
188 | dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", | ||
189 | __FUNCTION__, cmd); | ||
190 | goto reset_needed; | ||
191 | } | ||
192 | |||
193 | intr = inw(uhci->io_addr + USBINTR); | ||
194 | if (intr & (~USBINTR_RESUME)) { | ||
195 | dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", | ||
196 | __FUNCTION__, intr); | ||
197 | goto reset_needed; | ||
198 | } | ||
199 | return; | ||
200 | |||
201 | reset_needed: | ||
202 | dev_dbg(uhci_dev(uhci), "Performing full reset\n"); | ||
203 | reset_hc(uhci); | ||
204 | } | 148 | } |
205 | 149 | ||
206 | /* | 150 | /* |
@@ -212,13 +156,13 @@ static void configure_hc(struct uhci_hcd *uhci) | |||
212 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); | 156 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); |
213 | 157 | ||
214 | /* Store the frame list base address */ | 158 | /* Store the frame list base address */ |
215 | outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); | 159 | outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); |
216 | 160 | ||
217 | /* Set the current frame number */ | 161 | /* Set the current frame number */ |
218 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); | 162 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); |
219 | 163 | ||
220 | /* Mark controller as running before we enable interrupts */ | 164 | /* Mark controller as not halted before we enable interrupts */ |
221 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | 165 | uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; |
222 | mb(); | 166 | mb(); |
223 | 167 | ||
224 | /* Enable PIRQ */ | 168 | /* Enable PIRQ */ |
@@ -319,6 +263,7 @@ __acquires(uhci->lock) | |||
319 | 263 | ||
320 | static void start_rh(struct uhci_hcd *uhci) | 264 | static void start_rh(struct uhci_hcd *uhci) |
321 | { | 265 | { |
266 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | ||
322 | uhci->is_stopped = 0; | 267 | uhci->is_stopped = 0; |
323 | smp_wmb(); | 268 | smp_wmb(); |
324 | 269 | ||
@@ -437,36 +382,21 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
437 | int i; | 382 | int i; |
438 | 383 | ||
439 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 384 | for (i = 0; i < UHCI_NUM_SKELQH; i++) |
440 | if (uhci->skelqh[i]) { | 385 | uhci_free_qh(uhci, uhci->skelqh[i]); |
441 | uhci_free_qh(uhci, uhci->skelqh[i]); | ||
442 | uhci->skelqh[i] = NULL; | ||
443 | } | ||
444 | 386 | ||
445 | if (uhci->term_td) { | 387 | uhci_free_td(uhci, uhci->term_td); |
446 | uhci_free_td(uhci, uhci->term_td); | ||
447 | uhci->term_td = NULL; | ||
448 | } | ||
449 | 388 | ||
450 | if (uhci->qh_pool) { | 389 | dma_pool_destroy(uhci->qh_pool); |
451 | dma_pool_destroy(uhci->qh_pool); | ||
452 | uhci->qh_pool = NULL; | ||
453 | } | ||
454 | 390 | ||
455 | if (uhci->td_pool) { | 391 | dma_pool_destroy(uhci->td_pool); |
456 | dma_pool_destroy(uhci->td_pool); | ||
457 | uhci->td_pool = NULL; | ||
458 | } | ||
459 | 392 | ||
460 | if (uhci->fl) { | 393 | kfree(uhci->frame_cpu); |
461 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | ||
462 | uhci->fl, uhci->fl->dma_handle); | ||
463 | uhci->fl = NULL; | ||
464 | } | ||
465 | 394 | ||
466 | if (uhci->dentry) { | 395 | dma_free_coherent(uhci_dev(uhci), |
467 | debugfs_remove(uhci->dentry); | 396 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
468 | uhci->dentry = NULL; | 397 | uhci->frame, uhci->frame_dma_handle); |
469 | } | 398 | |
399 | debugfs_remove(uhci->dentry); | ||
470 | } | 400 | } |
471 | 401 | ||
472 | static int uhci_reset(struct usb_hcd *hcd) | 402 | static int uhci_reset(struct usb_hcd *hcd) |
@@ -545,7 +475,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
545 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 475 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
546 | int retval = -EBUSY; | 476 | int retval = -EBUSY; |
547 | int i; | 477 | int i; |
548 | dma_addr_t dma_handle; | ||
549 | struct dentry *dentry; | 478 | struct dentry *dentry; |
550 | 479 | ||
551 | hcd->uses_new_polling = 1; | 480 | hcd->uses_new_polling = 1; |
@@ -579,17 +508,23 @@ static int uhci_start(struct usb_hcd *hcd) | |||
579 | 508 | ||
580 | init_waitqueue_head(&uhci->waitqh); | 509 | init_waitqueue_head(&uhci->waitqh); |
581 | 510 | ||
582 | uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 511 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), |
583 | &dma_handle, 0); | 512 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
584 | if (!uhci->fl) { | 513 | &uhci->frame_dma_handle, 0); |
514 | if (!uhci->frame) { | ||
585 | dev_err(uhci_dev(uhci), "unable to allocate " | 515 | dev_err(uhci_dev(uhci), "unable to allocate " |
586 | "consistent memory for frame list\n"); | 516 | "consistent memory for frame list\n"); |
587 | goto err_alloc_fl; | 517 | goto err_alloc_frame; |
588 | } | 518 | } |
519 | memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); | ||
589 | 520 | ||
590 | memset((void *)uhci->fl, 0, sizeof(*uhci->fl)); | 521 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), |
591 | 522 | GFP_KERNEL); | |
592 | uhci->fl->dma_handle = dma_handle; | 523 | if (!uhci->frame_cpu) { |
524 | dev_err(uhci_dev(uhci), "unable to allocate " | ||
525 | "memory for frame pointers\n"); | ||
526 | goto err_alloc_frame_cpu; | ||
527 | } | ||
593 | 528 | ||
594 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), | 529 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
595 | sizeof(struct uhci_td), 16, 0); | 530 | sizeof(struct uhci_td), 16, 0); |
@@ -672,7 +607,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
672 | irq = 7; | 607 | irq = 7; |
673 | 608 | ||
674 | /* Only place we don't use the frame list routines */ | 609 | /* Only place we don't use the frame list routines */ |
675 | uhci->fl->frame[i] = UHCI_PTR_QH | | 610 | uhci->frame[i] = UHCI_PTR_QH | |
676 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | 611 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); |
677 | } | 612 | } |
678 | 613 | ||
@@ -690,31 +625,29 @@ static int uhci_start(struct usb_hcd *hcd) | |||
690 | * error exits: | 625 | * error exits: |
691 | */ | 626 | */ |
692 | err_alloc_skelqh: | 627 | err_alloc_skelqh: |
693 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 628 | for (i = 0; i < UHCI_NUM_SKELQH; i++) { |
694 | if (uhci->skelqh[i]) { | 629 | if (uhci->skelqh[i]) |
695 | uhci_free_qh(uhci, uhci->skelqh[i]); | 630 | uhci_free_qh(uhci, uhci->skelqh[i]); |
696 | uhci->skelqh[i] = NULL; | 631 | } |
697 | } | ||
698 | 632 | ||
699 | uhci_free_td(uhci, uhci->term_td); | 633 | uhci_free_td(uhci, uhci->term_td); |
700 | uhci->term_td = NULL; | ||
701 | 634 | ||
702 | err_alloc_term_td: | 635 | err_alloc_term_td: |
703 | dma_pool_destroy(uhci->qh_pool); | 636 | dma_pool_destroy(uhci->qh_pool); |
704 | uhci->qh_pool = NULL; | ||
705 | 637 | ||
706 | err_create_qh_pool: | 638 | err_create_qh_pool: |
707 | dma_pool_destroy(uhci->td_pool); | 639 | dma_pool_destroy(uhci->td_pool); |
708 | uhci->td_pool = NULL; | ||
709 | 640 | ||
710 | err_create_td_pool: | 641 | err_create_td_pool: |
711 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 642 | kfree(uhci->frame_cpu); |
712 | uhci->fl, uhci->fl->dma_handle); | 643 | |
713 | uhci->fl = NULL; | 644 | err_alloc_frame_cpu: |
645 | dma_free_coherent(uhci_dev(uhci), | ||
646 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | ||
647 | uhci->frame, uhci->frame_dma_handle); | ||
714 | 648 | ||
715 | err_alloc_fl: | 649 | err_alloc_frame: |
716 | debugfs_remove(uhci->dentry); | 650 | debugfs_remove(uhci->dentry); |
717 | uhci->dentry = NULL; | ||
718 | 651 | ||
719 | err_create_debug_entry: | 652 | err_create_debug_entry: |
720 | return retval; | 653 | return retval; |
@@ -726,7 +659,7 @@ static void uhci_stop(struct usb_hcd *hcd) | |||
726 | 659 | ||
727 | spin_lock_irq(&uhci->lock); | 660 | spin_lock_irq(&uhci->lock); |
728 | if (!uhci->hc_inaccessible) | 661 | if (!uhci->hc_inaccessible) |
729 | reset_hc(uhci); | 662 | hc_died(uhci); |
730 | uhci_scan_schedule(uhci, NULL); | 663 | uhci_scan_schedule(uhci, NULL); |
731 | spin_unlock_irq(&uhci->lock); | 664 | spin_unlock_irq(&uhci->lock); |
732 | 665 | ||
@@ -774,14 +707,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
774 | if (uhci->hc_inaccessible) /* Dead or already suspended */ | 707 | if (uhci->hc_inaccessible) /* Dead or already suspended */ |
775 | goto done; | 708 | goto done; |
776 | 709 | ||
777 | #ifndef CONFIG_USB_SUSPEND | ||
778 | /* Otherwise this would never happen */ | ||
779 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | ||
780 | #endif | ||
781 | |||
782 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { | 710 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { |
783 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); | 711 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); |
784 | hcd->state = HC_STATE_RUNNING; | ||
785 | rc = -EBUSY; | 712 | rc = -EBUSY; |
786 | goto done; | 713 | goto done; |
787 | }; | 714 | }; |
@@ -820,10 +747,6 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
820 | check_and_reset_hc(uhci); | 747 | check_and_reset_hc(uhci); |
821 | configure_hc(uhci); | 748 | configure_hc(uhci); |
822 | 749 | ||
823 | #ifndef CONFIG_USB_SUSPEND | ||
824 | /* Otherwise this would never happen */ | ||
825 | wakeup_rh(uhci); | ||
826 | #endif | ||
827 | if (uhci->rh_state == UHCI_RH_RESET) | 750 | if (uhci->rh_state == UHCI_RH_RESET) |
828 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 751 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
829 | 752 | ||
@@ -881,8 +804,8 @@ static const struct hc_driver uhci_driver = { | |||
881 | #ifdef CONFIG_PM | 804 | #ifdef CONFIG_PM |
882 | .suspend = uhci_suspend, | 805 | .suspend = uhci_suspend, |
883 | .resume = uhci_resume, | 806 | .resume = uhci_resume, |
884 | .hub_suspend = uhci_rh_suspend, | 807 | .bus_suspend = uhci_rh_suspend, |
885 | .hub_resume = uhci_rh_resume, | 808 | .bus_resume = uhci_rh_resume, |
886 | #endif | 809 | #endif |
887 | .stop = uhci_stop, | 810 | .stop = uhci_stop, |
888 | 811 | ||
@@ -908,6 +831,7 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); | |||
908 | static struct pci_driver uhci_pci_driver = { | 831 | static struct pci_driver uhci_pci_driver = { |
909 | .name = (char *)hcd_name, | 832 | .name = (char *)hcd_name, |
910 | .id_table = uhci_pci_ids, | 833 | .id_table = uhci_pci_ids, |
834 | .owner = THIS_MODULE, | ||
911 | 835 | ||
912 | .probe = usb_hcd_pci_probe, | 836 | .probe = usb_hcd_pci_probe, |
913 | .remove = usb_hcd_pci_remove, | 837 | .remove = usb_hcd_pci_remove, |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 282f40b75881..e576db57a926 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) | 7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) |
8 | #define PIPE_DEVEP_MASK 0x0007ff00 | 8 | #define PIPE_DEVEP_MASK 0x0007ff00 |
9 | 9 | ||
10 | |||
10 | /* | 11 | /* |
11 | * Universal Host Controller Interface data structures and defines | 12 | * Universal Host Controller Interface data structures and defines |
12 | */ | 13 | */ |
@@ -82,15 +83,10 @@ | |||
82 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
83 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ |
84 | 85 | ||
85 | struct uhci_frame_list { | ||
86 | __le32 frame[UHCI_NUMFRAMES]; | ||
87 | |||
88 | void *frame_cpu[UHCI_NUMFRAMES]; | ||
89 | |||
90 | dma_addr_t dma_handle; | ||
91 | }; | ||
92 | 86 | ||
93 | struct urb_priv; | 87 | /* |
88 | * Queue Headers | ||
89 | */ | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is | 92 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is |
@@ -116,13 +112,13 @@ struct uhci_qh { | |||
116 | 112 | ||
117 | struct urb_priv *urbp; | 113 | struct urb_priv *urbp; |
118 | 114 | ||
119 | struct list_head list; /* P: uhci->frame_list_lock */ | 115 | struct list_head list; |
120 | struct list_head remove_list; /* P: uhci->remove_list_lock */ | 116 | struct list_head remove_list; |
121 | } __attribute__((aligned(16))); | 117 | } __attribute__((aligned(16))); |
122 | 118 | ||
123 | /* | 119 | /* |
124 | * We need a special accessor for the element pointer because it is | 120 | * We need a special accessor for the element pointer because it is |
125 | * subject to asynchronous updates by the controller | 121 | * subject to asynchronous updates by the controller. |
126 | */ | 122 | */ |
127 | static __le32 inline qh_element(struct uhci_qh *qh) { | 123 | static __le32 inline qh_element(struct uhci_qh *qh) { |
128 | __le32 element = qh->element; | 124 | __le32 element = qh->element; |
@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
131 | return element; | 127 | return element; |
132 | } | 128 | } |
133 | 129 | ||
130 | |||
131 | /* | ||
132 | * Transfer Descriptors | ||
133 | */ | ||
134 | |||
134 | /* | 135 | /* |
135 | * for TD <status>: | 136 | * for TD <status>: |
136 | */ | 137 | */ |
@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
183 | * | 184 | * |
184 | * That's silly, the hardware doesn't care. The hardware only cares that | 185 | * That's silly, the hardware doesn't care. The hardware only cares that |
185 | * the hardware words are 16-byte aligned, and we can have any amount of | 186 | * the hardware words are 16-byte aligned, and we can have any amount of |
186 | * sw space after the TD entry as far as I can tell. | 187 | * sw space after the TD entry. |
187 | * | ||
188 | * But let's just go with the documentation, at least for 32-bit machines. | ||
189 | * On 64-bit machines we probably want to take advantage of the fact that | ||
190 | * hw doesn't really care about the size of the sw-only area. | ||
191 | * | ||
192 | * Alas, not anymore, we have more than 4 words for software, woops. | ||
193 | * Everything still works tho, surprise! -jerdfelt | ||
194 | * | 188 | * |
195 | * td->link points to either another TD (not necessarily for the same urb or | 189 | * td->link points to either another TD (not necessarily for the same urb or |
196 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs) | 190 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). |
197 | */ | 191 | */ |
198 | struct uhci_td { | 192 | struct uhci_td { |
199 | /* Hardware fields */ | 193 | /* Hardware fields */ |
@@ -205,18 +199,16 @@ struct uhci_td { | |||
205 | /* Software fields */ | 199 | /* Software fields */ |
206 | dma_addr_t dma_handle; | 200 | dma_addr_t dma_handle; |
207 | 201 | ||
208 | struct urb *urb; | 202 | struct list_head list; |
209 | 203 | struct list_head remove_list; | |
210 | struct list_head list; /* P: urb->lock */ | ||
211 | struct list_head remove_list; /* P: uhci->td_remove_list_lock */ | ||
212 | 204 | ||
213 | int frame; /* for iso: what frame? */ | 205 | int frame; /* for iso: what frame? */ |
214 | struct list_head fl_list; /* P: uhci->frame_list_lock */ | 206 | struct list_head fl_list; |
215 | } __attribute__((aligned(16))); | 207 | } __attribute__((aligned(16))); |
216 | 208 | ||
217 | /* | 209 | /* |
218 | * We need a special accessor for the control/status word because it is | 210 | * We need a special accessor for the control/status word because it is |
219 | * subject to asynchronous updates by the controller | 211 | * subject to asynchronous updates by the controller. |
220 | */ | 212 | */ |
221 | static u32 inline td_status(struct uhci_td *td) { | 213 | static u32 inline td_status(struct uhci_td *td) { |
222 | __le32 status = td->status; | 214 | __le32 status = td->status; |
@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
227 | 219 | ||
228 | 220 | ||
229 | /* | 221 | /* |
222 | * Skeleton Queue Headers | ||
223 | */ | ||
224 | |||
225 | /* | ||
230 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both |
231 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TD's for one transfer, and also to faciliate queuing |
232 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URB's. To make it easy to insert entries into the schedule, we have |
@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) { | |||
256 | * | 252 | * |
257 | * The terminating QH is used for 2 reasons: | 253 | * The terminating QH is used for 2 reasons: |
258 | * - To place a terminating TD which is used to workaround a PIIX bug | 254 | * - To place a terminating TD which is used to workaround a PIIX bug |
259 | * (see Intel errata for explanation) | 255 | * (see Intel errata for explanation), and |
260 | * - To loop back to the full-speed control queue for full-speed bandwidth | 256 | * - To loop back to the full-speed control queue for full-speed bandwidth |
261 | * reclamation | 257 | * reclamation. |
262 | * | 258 | * |
263 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
264 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the |
265 | * use of QH's for Isochronous, it doesn't use them either. Since we don't | 261 | * use of QH's for Isochronous, it doesn't use them either. And the spec |
266 | * need to use them either, we follow the spec diagrams in hope that it'll | 262 | * says that queues never advance on an error completion status, which |
267 | * be more compatible with future UHCI implementations. | 263 | * makes them totally unsuitable for Isochronous transfers. |
268 | */ | 264 | */ |
269 | 265 | ||
270 | #define UHCI_NUM_SKELQH 12 | 266 | #define UHCI_NUM_SKELQH 12 |
@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int interval) | |||
314 | return 0; /* int128 for 128-255 ms (Max.) */ | 310 | return 0; /* int128 for 128-255 ms (Max.) */ |
315 | } | 311 | } |
316 | 312 | ||
313 | |||
314 | /* | ||
315 | * The UHCI controller and root hub | ||
316 | */ | ||
317 | |||
317 | /* | 318 | /* |
318 | * States for the root hub. | 319 | * States for the root hub: |
319 | * | 320 | * |
320 | * To prevent "bouncing" in the presence of electrical noise, | 321 | * To prevent "bouncing" in the presence of electrical noise, |
321 | * when there are no devices attached we delay for 1 second in the | 322 | * when there are no devices attached we delay for 1 second in the |
@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int interval) | |||
326 | */ | 327 | */ |
327 | enum uhci_rh_state { | 328 | enum uhci_rh_state { |
328 | /* In the following states the HC must be halted. | 329 | /* In the following states the HC must be halted. |
329 | * These two must come first */ | 330 | * These two must come first. */ |
330 | UHCI_RH_RESET, | 331 | UHCI_RH_RESET, |
331 | UHCI_RH_SUSPENDED, | 332 | UHCI_RH_SUSPENDED, |
332 | 333 | ||
@@ -338,13 +339,13 @@ enum uhci_rh_state { | |||
338 | UHCI_RH_SUSPENDING, | 339 | UHCI_RH_SUSPENDING, |
339 | 340 | ||
340 | /* In the following states it's an error if the HC is halted. | 341 | /* In the following states it's an error if the HC is halted. |
341 | * These two must come last */ | 342 | * These two must come last. */ |
342 | UHCI_RH_RUNNING, /* The normal state */ | 343 | UHCI_RH_RUNNING, /* The normal state */ |
343 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ | 344 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ |
344 | }; | 345 | }; |
345 | 346 | ||
346 | /* | 347 | /* |
347 | * This describes the full uhci information. | 348 | * The full UHCI controller information: |
348 | */ | 349 | */ |
349 | struct uhci_hcd { | 350 | struct uhci_hcd { |
350 | 351 | ||
@@ -361,7 +362,11 @@ struct uhci_hcd { | |||
361 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ |
362 | 363 | ||
363 | spinlock_t lock; | 364 | spinlock_t lock; |
364 | struct uhci_frame_list *fl; /* P: uhci->lock */ | 365 | |
366 | dma_addr_t frame_dma_handle; /* Hardware frame list */ | ||
367 | __le32 *frame; | ||
368 | void **frame_cpu; /* CPU's frame list */ | ||
369 | |||
365 | int fsbr; /* Full-speed bandwidth reclamation */ | 370 | int fsbr; /* Full-speed bandwidth reclamation */ |
366 | unsigned long fsbrtimeout; /* FSBR delay */ | 371 | unsigned long fsbrtimeout; /* FSBR delay */ |
367 | 372 | ||
@@ -385,22 +390,22 @@ struct uhci_hcd { | |||
385 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
386 | 391 | ||
387 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URB's currently controlled by this HC */ |
388 | struct list_head urb_list; /* P: uhci->lock */ | 393 | struct list_head urb_list; |
389 | 394 | ||
390 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QH's that are done, but waiting to be unlinked (race) */ |
391 | struct list_head qh_remove_list; /* P: uhci->lock */ | 396 | struct list_head qh_remove_list; |
392 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
393 | 398 | ||
394 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TD's that are done, but waiting to be freed (race) */ |
395 | struct list_head td_remove_list; /* P: uhci->lock */ | 400 | struct list_head td_remove_list; |
396 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
397 | 402 | ||
398 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URB's */ |
399 | struct list_head urb_remove_list; /* P: uhci->lock */ | 404 | struct list_head urb_remove_list; |
400 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
401 | 406 | ||
402 | /* List of URB's awaiting completion callback */ | 407 | /* List of URB's awaiting completion callback */ |
403 | struct list_head complete_list; /* P: uhci->lock */ | 408 | struct list_head complete_list; |
404 | 409 | ||
405 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
406 | 411 | ||
@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) | |||
419 | 424 | ||
420 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) | 425 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) |
421 | 426 | ||
427 | |||
428 | /* | ||
429 | * Private per-URB data | ||
430 | */ | ||
422 | struct urb_priv { | 431 | struct urb_priv { |
423 | struct list_head urb_list; | 432 | struct list_head urb_list; |
424 | 433 | ||
425 | struct urb *urb; | 434 | struct urb *urb; |
426 | 435 | ||
427 | struct uhci_qh *qh; /* QH for this URB */ | 436 | struct uhci_qh *qh; /* QH for this URB */ |
428 | struct list_head td_list; /* P: urb->lock */ | 437 | struct list_head td_list; |
429 | 438 | ||
430 | unsigned fsbr : 1; /* URB turned on FSBR */ | 439 | unsigned fsbr : 1; /* URB turned on FSBR */ |
431 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ | 440 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ |
@@ -434,12 +443,12 @@ struct urb_priv { | |||
434 | /* a control transfer, retrigger */ | 443 | /* a control transfer, retrigger */ |
435 | /* the status phase */ | 444 | /* the status phase */ |
436 | 445 | ||
437 | unsigned long inserttime; /* In jiffies */ | ||
438 | unsigned long fsbrtime; /* In jiffies */ | 446 | unsigned long fsbrtime; /* In jiffies */ |
439 | 447 | ||
440 | struct list_head queue_list; /* P: uhci->frame_list_lock */ | 448 | struct list_head queue_list; |
441 | }; | 449 | }; |
442 | 450 | ||
451 | |||
443 | /* | 452 | /* |
444 | * Locking in uhci.c | 453 | * Locking in uhci.c |
445 | * | 454 | * |
@@ -459,6 +468,5 @@ struct urb_priv { | |||
459 | 468 | ||
460 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 469 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
461 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 | 470 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 |
462 | #define PCI_DEVICE_ID_GL880S_EHCI 0x8084 | ||
463 | 471 | ||
464 | #endif | 472 | #endif |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 4e0fbe2c1a9a..7e46887d9e12 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
89 | td->frame = framenum; | 89 | td->frame = framenum; |
90 | 90 | ||
91 | /* Is there a TD already mapped there? */ | 91 | /* Is there a TD already mapped there? */ |
92 | if (uhci->fl->frame_cpu[framenum]) { | 92 | if (uhci->frame_cpu[framenum]) { |
93 | struct uhci_td *ftd, *ltd; | 93 | struct uhci_td *ftd, *ltd; |
94 | 94 | ||
95 | ftd = uhci->fl->frame_cpu[framenum]; | 95 | ftd = uhci->frame_cpu[framenum]; |
96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); | 96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); |
97 | 97 | ||
98 | list_add_tail(&td->fl_list, &ftd->fl_list); | 98 | list_add_tail(&td->fl_list, &ftd->fl_list); |
@@ -101,29 +101,32 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
101 | wmb(); | 101 | wmb(); |
102 | ltd->link = cpu_to_le32(td->dma_handle); | 102 | ltd->link = cpu_to_le32(td->dma_handle); |
103 | } else { | 103 | } else { |
104 | td->link = uhci->fl->frame[framenum]; | 104 | td->link = uhci->frame[framenum]; |
105 | wmb(); | 105 | wmb(); |
106 | uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle); | 106 | uhci->frame[framenum] = cpu_to_le32(td->dma_handle); |
107 | uhci->fl->frame_cpu[framenum] = td; | 107 | uhci->frame_cpu[framenum] = td; |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | 111 | static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci, |
112 | struct uhci_td *td) | ||
112 | { | 113 | { |
113 | /* If it's not inserted, don't remove it */ | 114 | /* If it's not inserted, don't remove it */ |
114 | if (td->frame == -1 && list_empty(&td->fl_list)) | 115 | if (td->frame == -1) { |
116 | WARN_ON(!list_empty(&td->fl_list)); | ||
115 | return; | 117 | return; |
118 | } | ||
116 | 119 | ||
117 | if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) { | 120 | if (uhci->frame_cpu[td->frame] == td) { |
118 | if (list_empty(&td->fl_list)) { | 121 | if (list_empty(&td->fl_list)) { |
119 | uhci->fl->frame[td->frame] = td->link; | 122 | uhci->frame[td->frame] = td->link; |
120 | uhci->fl->frame_cpu[td->frame] = NULL; | 123 | uhci->frame_cpu[td->frame] = NULL; |
121 | } else { | 124 | } else { |
122 | struct uhci_td *ntd; | 125 | struct uhci_td *ntd; |
123 | 126 | ||
124 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 127 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); |
125 | uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle); | 128 | uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); |
126 | uhci->fl->frame_cpu[td->frame] = ntd; | 129 | uhci->frame_cpu[td->frame] = ntd; |
127 | } | 130 | } |
128 | } else { | 131 | } else { |
129 | struct uhci_td *ptd; | 132 | struct uhci_td *ptd; |
@@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | |||
132 | ptd->link = td->link; | 135 | ptd->link = td->link; |
133 | } | 136 | } |
134 | 137 | ||
135 | wmb(); | ||
136 | td->link = UHCI_PTR_TERM; | ||
137 | |||
138 | list_del_init(&td->fl_list); | 138 | list_del_init(&td->fl_list); |
139 | td->frame = -1; | 139 | td->frame = -1; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) | ||
143 | { | ||
144 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
145 | struct uhci_td *td; | ||
146 | |||
147 | list_for_each_entry(td, &urbp->td_list, list) | ||
148 | uhci_remove_td_frame_list(uhci, td); | ||
149 | wmb(); | ||
150 | } | ||
151 | |||
142 | /* | 152 | /* |
143 | * Inserts a td list into qh. | 153 | * Inserts a td list into qh. |
144 | */ | 154 | */ |
@@ -443,7 +453,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u | |||
443 | 453 | ||
444 | memset((void *)urbp, 0, sizeof(*urbp)); | 454 | memset((void *)urbp, 0, sizeof(*urbp)); |
445 | 455 | ||
446 | urbp->inserttime = jiffies; | ||
447 | urbp->fsbrtime = jiffies; | 456 | urbp->fsbrtime = jiffies; |
448 | urbp->urb = urb; | 457 | urbp->urb = urb; |
449 | 458 | ||
@@ -462,8 +471,6 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) | |||
462 | { | 471 | { |
463 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; | 472 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; |
464 | 473 | ||
465 | td->urb = urb; | ||
466 | |||
467 | list_add_tail(&td->list, &urbp->td_list); | 474 | list_add_tail(&td->list, &urbp->td_list); |
468 | } | 475 | } |
469 | 476 | ||
@@ -473,8 +480,6 @@ static void uhci_remove_td_from_urb(struct uhci_td *td) | |||
473 | return; | 480 | return; |
474 | 481 | ||
475 | list_del_init(&td->list); | 482 | list_del_init(&td->list); |
476 | |||
477 | td->urb = NULL; | ||
478 | } | 483 | } |
479 | 484 | ||
480 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | 485 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) |
@@ -503,7 +508,6 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
503 | 508 | ||
504 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { | 509 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { |
505 | uhci_remove_td_from_urb(td); | 510 | uhci_remove_td_from_urb(td); |
506 | uhci_remove_td(uhci, td); | ||
507 | list_add(&td->remove_list, &uhci->td_remove_list); | 511 | list_add(&td->remove_list, &uhci->td_remove_list); |
508 | } | 512 | } |
509 | 513 | ||
@@ -1073,6 +1077,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1073 | struct uhci_td *td; | 1077 | struct uhci_td *td; |
1074 | int i, ret, frame; | 1078 | int i, ret, frame; |
1075 | int status, destination; | 1079 | int status, destination; |
1080 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
1076 | 1081 | ||
1077 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; | 1082 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; |
1078 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); | 1083 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); |
@@ -1081,11 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1081 | if (ret) | 1086 | if (ret) |
1082 | return ret; | 1087 | return ret; |
1083 | 1088 | ||
1084 | frame = urb->start_frame; | 1089 | for (i = 0; i < urb->number_of_packets; i++) { |
1085 | for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) { | ||
1086 | if (!urb->iso_frame_desc[i].length) | ||
1087 | continue; | ||
1088 | |||
1089 | td = uhci_alloc_td(uhci); | 1090 | td = uhci_alloc_td(uhci); |
1090 | if (!td) | 1091 | if (!td) |
1091 | return -ENOMEM; | 1092 | return -ENOMEM; |
@@ -1096,8 +1097,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1096 | 1097 | ||
1097 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
1098 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1099 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
1100 | } | ||
1099 | 1101 | ||
1102 | frame = urb->start_frame; | ||
1103 | list_for_each_entry(td, &urbp->td_list, list) { | ||
1100 | uhci_insert_td_frame_list(uhci, td, frame); | 1104 | uhci_insert_td_frame_list(uhci, td, frame); |
1105 | frame += urb->interval; | ||
1101 | } | 1106 | } |
1102 | 1107 | ||
1103 | return -EINPROGRESS; | 1108 | return -EINPROGRESS; |
@@ -1110,7 +1115,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1110 | int status; | 1115 | int status; |
1111 | int i, ret = 0; | 1116 | int i, ret = 0; |
1112 | 1117 | ||
1113 | urb->actual_length = 0; | 1118 | urb->actual_length = urb->error_count = 0; |
1114 | 1119 | ||
1115 | i = 0; | 1120 | i = 0; |
1116 | list_for_each_entry(td, &urbp->td_list, list) { | 1121 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1134,6 +1139,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1134 | 1139 | ||
1135 | i++; | 1140 | i++; |
1136 | } | 1141 | } |
1142 | unlink_isochronous_tds(uhci, urb); | ||
1137 | 1143 | ||
1138 | return ret; | 1144 | return ret; |
1139 | } | 1145 | } |
@@ -1366,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1366 | goto done; | 1372 | goto done; |
1367 | list_del_init(&urbp->urb_list); | 1373 | list_del_init(&urbp->urb_list); |
1368 | 1374 | ||
1375 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
1376 | unlink_isochronous_tds(uhci, urb); | ||
1369 | uhci_unlink_generic(uhci, urb); | 1377 | uhci_unlink_generic(uhci, urb); |
1370 | 1378 | ||
1371 | uhci_get_current_frame_number(uhci); | 1379 | uhci_get_current_frame_number(uhci); |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a330a4b50e16..1d973bcf56aa 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -425,9 +425,8 @@ static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res) | |||
425 | static struct usb_driver mdc800_usb_driver; | 425 | static struct usb_driver mdc800_usb_driver; |
426 | static struct file_operations mdc800_device_ops; | 426 | static struct file_operations mdc800_device_ops; |
427 | static struct usb_class_driver mdc800_class = { | 427 | static struct usb_class_driver mdc800_class = { |
428 | .name = "usb/mdc800%d", | 428 | .name = "mdc800%d", |
429 | .fops = &mdc800_device_ops, | 429 | .fops = &mdc800_device_ops, |
430 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, | ||
431 | .minor_base = MDC800_DEVICE_MINOR_BASE, | 430 | .minor_base = MDC800_DEVICE_MINOR_BASE, |
432 | }; | 431 | }; |
433 | 432 | ||
@@ -976,13 +975,13 @@ static struct usb_driver mdc800_usb_driver = | |||
976 | Init and Cleanup this driver (Main Functions) | 975 | Init and Cleanup this driver (Main Functions) |
977 | *************************************************************************/ | 976 | *************************************************************************/ |
978 | 977 | ||
979 | #define try(A) if (!(A)) goto cleanup_on_fail; | ||
980 | |||
981 | static int __init usb_mdc800_init (void) | 978 | static int __init usb_mdc800_init (void) |
982 | { | 979 | { |
983 | int retval = -ENODEV; | 980 | int retval = -ENODEV; |
984 | /* Allocate Memory */ | 981 | /* Allocate Memory */ |
985 | try (mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL)); | 982 | mdc800=kmalloc (sizeof (struct mdc800_data), GFP_KERNEL); |
983 | if (!mdc800) | ||
984 | goto cleanup_on_fail; | ||
986 | 985 | ||
987 | memset(mdc800, 0, sizeof(struct mdc800_data)); | 986 | memset(mdc800, 0, sizeof(struct mdc800_data)); |
988 | mdc800->dev = NULL; | 987 | mdc800->dev = NULL; |
@@ -998,13 +997,25 @@ static int __init usb_mdc800_init (void) | |||
998 | mdc800->downloaded = 0; | 997 | mdc800->downloaded = 0; |
999 | mdc800->written = 0; | 998 | mdc800->written = 0; |
1000 | 999 | ||
1001 | try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); | 1000 | mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL); |
1002 | try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); | 1001 | if (!mdc800->irq_urb_buffer) |
1003 | try (mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL)); | 1002 | goto cleanup_on_fail; |
1003 | mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL); | ||
1004 | if (!mdc800->write_urb_buffer) | ||
1005 | goto cleanup_on_fail; | ||
1006 | mdc800->download_urb_buffer=kmalloc (64, GFP_KERNEL); | ||
1007 | if (!mdc800->download_urb_buffer) | ||
1008 | goto cleanup_on_fail; | ||
1004 | 1009 | ||
1005 | try (mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL)); | 1010 | mdc800->irq_urb=usb_alloc_urb (0, GFP_KERNEL); |
1006 | try (mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL)); | 1011 | if (!mdc800->irq_urb) |
1007 | try (mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL)); | 1012 | goto cleanup_on_fail; |
1013 | mdc800->download_urb=usb_alloc_urb (0, GFP_KERNEL); | ||
1014 | if (!mdc800->download_urb) | ||
1015 | goto cleanup_on_fail; | ||
1016 | mdc800->write_urb=usb_alloc_urb (0, GFP_KERNEL); | ||
1017 | if (!mdc800->write_urb) | ||
1018 | goto cleanup_on_fail; | ||
1008 | 1019 | ||
1009 | /* Register the driver */ | 1020 | /* Register the driver */ |
1010 | retval = usb_register(&mdc800_usb_driver); | 1021 | retval = usb_register(&mdc800_usb_driver); |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index c84e1486054f..c89d0769b3da 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -773,11 +773,10 @@ static int mts_usb_probe(struct usb_interface *intf, | |||
773 | } | 773 | } |
774 | 774 | ||
775 | 775 | ||
776 | new_desc = kmalloc(sizeof(struct mts_desc), GFP_KERNEL); | 776 | new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); |
777 | if (!new_desc) | 777 | if (!new_desc) |
778 | goto out; | 778 | goto out; |
779 | 779 | ||
780 | memset(new_desc, 0, sizeof(*new_desc)); | ||
781 | new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); | 780 | new_desc->urb = usb_alloc_urb(0, GFP_KERNEL); |
782 | if (!new_desc->urb) | 781 | if (!new_desc->urb) |
783 | goto out_kfree; | 782 | goto out_kfree; |
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 1c5205321d83..1c3b472a3bca 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -2154,7 +2154,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2154 | * input_handles associated with this input device. | 2154 | * input_handles associated with this input device. |
2155 | * What identifies an evdev input_handler is that it begins | 2155 | * What identifies an evdev input_handler is that it begins |
2156 | * with 'event', continues with a digit, and that in turn | 2156 | * with 'event', continues with a digit, and that in turn |
2157 | * is mapped to /{devfs}/input/eventN. | 2157 | * is mapped to input/eventN. |
2158 | */ | 2158 | */ |
2159 | list_for_each_safe(node, next, &inputdev->h_list) { | 2159 | list_for_each_safe(node, next, &inputdev->h_list) { |
2160 | inputhandle = to_handle(node); | 2160 | inputhandle = to_handle(node); |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 411a0645a7a3..79ddce4555ab 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1784,6 +1784,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1784 | hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; | 1784 | hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; |
1785 | hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); | 1785 | hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
1786 | 1786 | ||
1787 | /* May be needed for some devices */ | ||
1788 | usb_clear_halt(hid->dev, hid->urbin->pipe); | ||
1789 | |||
1787 | return hid; | 1790 | return hid; |
1788 | 1791 | ||
1789 | fail: | 1792 | fail: |
@@ -1887,7 +1890,6 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) | |||
1887 | struct hid_device *hid = usb_get_intfdata (intf); | 1890 | struct hid_device *hid = usb_get_intfdata (intf); |
1888 | 1891 | ||
1889 | usb_kill_urb(hid->urbin); | 1892 | usb_kill_urb(hid->urbin); |
1890 | intf->dev.power.power_state = PMSG_SUSPEND; | ||
1891 | dev_dbg(&intf->dev, "suspend\n"); | 1893 | dev_dbg(&intf->dev, "suspend\n"); |
1892 | return 0; | 1894 | return 0; |
1893 | } | 1895 | } |
@@ -1897,7 +1899,6 @@ static int hid_resume(struct usb_interface *intf) | |||
1897 | struct hid_device *hid = usb_get_intfdata (intf); | 1899 | struct hid_device *hid = usb_get_intfdata (intf); |
1898 | int status; | 1900 | int status; |
1899 | 1901 | ||
1900 | intf->dev.power.power_state = PMSG_ON; | ||
1901 | if (hid->open) | 1902 | if (hid->open) |
1902 | status = usb_submit_urb(hid->urbin, GFP_NOIO); | 1903 | status = usb_submit_urb(hid->urbin, GFP_NOIO); |
1903 | else | 1904 | else |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index d32427818af7..440377c7a0da 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -732,9 +732,8 @@ static struct file_operations hiddev_fops = { | |||
732 | }; | 732 | }; |
733 | 733 | ||
734 | static struct usb_class_driver hiddev_class = { | 734 | static struct usb_class_driver hiddev_class = { |
735 | .name = "usb/hid/hiddev%d", | 735 | .name = "hiddev%d", |
736 | .fops = &hiddev_fops, | 736 | .fops = &hiddev_fops, |
737 | .mode = S_IFCHR | S_IRUGO | S_IWUSR, | ||
738 | .minor_base = HIDDEV_MINOR_BASE, | 737 | .minor_base = HIDDEV_MINOR_BASE, |
739 | }; | 738 | }; |
740 | 739 | ||
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h index 52ff27f15127..a424094d9fe2 100644 --- a/drivers/usb/input/map_to_7segment.h +++ b/drivers/usb/input/map_to_7segment.h | |||
@@ -79,7 +79,7 @@ struct seg7_conversion_map { | |||
79 | 79 | ||
80 | static inline int map_to_seg7(struct seg7_conversion_map *map, int c) | 80 | static inline int map_to_seg7(struct seg7_conversion_map *map, int c) |
81 | { | 81 | { |
82 | return c & 0x7f ? map->table[c] : -EINVAL; | 82 | return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL; |
83 | } | 83 | } |
84 | 84 | ||
85 | #define SEG7_CONVERSION_MAP(_name, _map) \ | 85 | #define SEG7_CONVERSION_MAP(_name, _map) \ |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 3766ccc271be..0043e6ebcd1f 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -75,7 +75,9 @@ struct touchkit_usb { | |||
75 | 75 | ||
76 | static struct usb_device_id touchkit_devices[] = { | 76 | static struct usb_device_id touchkit_devices[] = { |
77 | {USB_DEVICE(0x3823, 0x0001)}, | 77 | {USB_DEVICE(0x3823, 0x0001)}, |
78 | {USB_DEVICE(0x0123, 0x0001)}, | ||
78 | {USB_DEVICE(0x0eef, 0x0001)}, | 79 | {USB_DEVICE(0x0eef, 0x0001)}, |
80 | {USB_DEVICE(0x0eef, 0x0002)}, | ||
79 | {} | 81 | {} |
80 | }; | 82 | }; |
81 | 83 | ||
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 6ca2fae99d2d..27b23c55bbc7 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c | |||
@@ -707,9 +707,8 @@ static struct file_operations dabusb_fops = | |||
707 | }; | 707 | }; |
708 | 708 | ||
709 | static struct usb_class_driver dabusb_class = { | 709 | static struct usb_class_driver dabusb_class = { |
710 | .name = "usb/dabusb%d", | 710 | .name = "dabusb%d", |
711 | .fops = &dabusb_fops, | 711 | .fops = &dabusb_fops, |
712 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, | ||
713 | .minor_base = DABUSB_MINOR, | 712 | .minor_base = DABUSB_MINOR, |
714 | }; | 713 | }; |
715 | 714 | ||
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index ae4681f9f0ea..5f33f7c64885 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -1873,9 +1873,8 @@ static struct file_operations auerswald_fops = | |||
1873 | }; | 1873 | }; |
1874 | 1874 | ||
1875 | static struct usb_class_driver auerswald_class = { | 1875 | static struct usb_class_driver auerswald_class = { |
1876 | .name = "usb/auer%d", | 1876 | .name = "auer%d", |
1877 | .fops = &auerswald_fops, | 1877 | .fops = &auerswald_fops, |
1878 | .mode = S_IFCHR | S_IRUGO | S_IWUGO, | ||
1879 | .minor_base = AUER_MINOR_BASE, | 1878 | .minor_base = AUER_MINOR_BASE, |
1880 | }; | 1879 | }; |
1881 | 1880 | ||
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 733acc213726..3944a55ed74c 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -105,11 +105,10 @@ static struct file_operations idmouse_fops = { | |||
105 | .release = idmouse_release, | 105 | .release = idmouse_release, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* class driver information for devfs */ | 108 | /* class driver information */ |
109 | static struct usb_class_driver idmouse_class = { | 109 | static struct usb_class_driver idmouse_class = { |
110 | .name = "usb/idmouse%d", | 110 | .name = "idmouse%d", |
111 | .fops = &idmouse_fops, | 111 | .fops = &idmouse_fops, |
112 | .mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */ | ||
113 | .minor_base = USB_IDMOUSE_MINOR_BASE, | 112 | .minor_base = USB_IDMOUSE_MINOR_BASE, |
114 | }; | 113 | }; |
115 | 114 | ||
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 7d06105763d4..2703e205bc8f 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -271,12 +271,11 @@ static struct file_operations tower_fops = { | |||
271 | 271 | ||
272 | /* | 272 | /* |
273 | * usb class driver info in order to get a minor number from the usb core, | 273 | * usb class driver info in order to get a minor number from the usb core, |
274 | * and to have the device registered with devfs and the driver core | 274 | * and to have the device registered with the driver core |
275 | */ | 275 | */ |
276 | static struct usb_class_driver tower_class = { | 276 | static struct usb_class_driver tower_class = { |
277 | .name = "usb/legousbtower%d", | 277 | .name = "legousbtower%d", |
278 | .fops = &tower_fops, | 278 | .fops = &tower_fops, |
279 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, | ||
280 | .minor_base = LEGO_USB_TOWER_MINOR_BASE, | 279 | .minor_base = LEGO_USB_TOWER_MINOR_BASE, |
281 | }; | 280 | }; |
282 | 281 | ||
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 26f77e29c7a6..7d02d8ec6b1a 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -443,9 +443,8 @@ file_operations usb_rio_fops = { | |||
443 | }; | 443 | }; |
444 | 444 | ||
445 | static struct usb_class_driver usb_rio_class = { | 445 | static struct usb_class_driver usb_rio_class = { |
446 | .name = "usb/rio500%d", | 446 | .name = "rio500%d", |
447 | .fops = &usb_rio_fops, | 447 | .fops = &usb_rio_fops, |
448 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, | ||
449 | .minor_base = RIO_MINOR, | 448 | .minor_base = RIO_MINOR, |
450 | }; | 449 | }; |
451 | 450 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 39db3155723a..c946c9a538a0 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -2440,7 +2440,7 @@ int | |||
2440 | sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | 2440 | sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) |
2441 | { | 2441 | { |
2442 | int ret = 0, slot = sisusb->font_slot, i; | 2442 | int ret = 0, slot = sisusb->font_slot, i; |
2443 | struct font_desc *myfont; | 2443 | const struct font_desc *myfont; |
2444 | u8 *tempbuf; | 2444 | u8 *tempbuf; |
2445 | u16 *tempbufb; | 2445 | u16 *tempbufb; |
2446 | size_t written; | 2446 | size_t written; |
@@ -3239,12 +3239,7 @@ static struct file_operations usb_sisusb_fops = { | |||
3239 | }; | 3239 | }; |
3240 | 3240 | ||
3241 | static struct usb_class_driver usb_sisusb_class = { | 3241 | static struct usb_class_driver usb_sisusb_class = { |
3242 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) | ||
3243 | .name = "usb/sisusbvga%d", | ||
3244 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, | ||
3245 | #else | ||
3246 | .name = "sisusbvga%d", | 3242 | .name = "sisusbvga%d", |
3247 | #endif | ||
3248 | .fops = &usb_sisusb_fops, | 3243 | .fops = &usb_sisusb_fops, |
3249 | .minor_base = SISUSB_MINOR | 3244 | .minor_base = SISUSB_MINOR |
3250 | }; | 3245 | }; |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 096ab3029676..85f3725334b0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -251,13 +251,12 @@ static struct file_operations lcd_fops = { | |||
251 | }; | 251 | }; |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * * usb class driver info in order to get a minor number from the usb core, | 254 | * usb class driver info in order to get a minor number from the usb core, |
255 | * * and to have the device registered with devfs and the driver core | 255 | * and to have the device registered with the driver core |
256 | * */ | 256 | */ |
257 | static struct usb_class_driver lcd_class = { | 257 | static struct usb_class_driver lcd_class = { |
258 | .name = "usb/lcd%d", | 258 | .name = "lcd%d", |
259 | .fops = &lcd_fops, | 259 | .fops = &lcd_fops, |
260 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, | ||
261 | .minor_base = USBLCD_MINOR, | 260 | .minor_base = USBLCD_MINOR, |
262 | }; | 261 | }; |
263 | 262 | ||
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 54799eb0bc60..90a96257d6ce 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -983,6 +983,7 @@ test_ctrl_queue (struct usbtest_dev *dev, struct usbtest_param *param) | |||
983 | reqp->number = i % NUM_SUBCASES; | 983 | reqp->number = i % NUM_SUBCASES; |
984 | reqp->expected = expected; | 984 | reqp->expected = expected; |
985 | u->setup_packet = (char *) &reqp->setup; | 985 | u->setup_packet = (char *) &reqp->setup; |
986 | u->transfer_flags |= URB_NO_SETUP_DMA_MAP; | ||
986 | 987 | ||
987 | u->context = &context; | 988 | u->context = &context; |
988 | u->complete = ctrl_complete; | 989 | u->complete = ctrl_complete; |
@@ -1948,21 +1949,11 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) | |||
1948 | 1949 | ||
1949 | static int usbtest_suspend (struct usb_interface *intf, pm_message_t message) | 1950 | static int usbtest_suspend (struct usb_interface *intf, pm_message_t message) |
1950 | { | 1951 | { |
1951 | struct usbtest_dev *dev = usb_get_intfdata (intf); | ||
1952 | |||
1953 | down (&dev->sem); | ||
1954 | intf->dev.power.power_state = PMSG_SUSPEND; | ||
1955 | up (&dev->sem); | ||
1956 | return 0; | 1952 | return 0; |
1957 | } | 1953 | } |
1958 | 1954 | ||
1959 | static int usbtest_resume (struct usb_interface *intf) | 1955 | static int usbtest_resume (struct usb_interface *intf) |
1960 | { | 1956 | { |
1961 | struct usbtest_dev *dev = usb_get_intfdata (intf); | ||
1962 | |||
1963 | down (&dev->sem); | ||
1964 | intf->dev.power.power_state = PMSG_ON; | ||
1965 | up (&dev->sem); | ||
1966 | return 0; | 1957 | return 0; |
1967 | } | 1958 | } |
1968 | 1959 | ||
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 508a21028db4..c34944c75047 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
12 | #include <linux/debugfs.h> | 12 | #include <linux/debugfs.h> |
13 | #include <linux/smp_lock.h> | 13 | #include <linux/smp_lock.h> |
14 | #include <linux/notifier.h> | ||
14 | 15 | ||
15 | #include "usb_mon.h" | 16 | #include "usb_mon.h" |
16 | #include "../core/hcd.h" | 17 | #include "../core/hcd.h" |
@@ -205,6 +206,23 @@ static void mon_bus_remove(struct usb_bus *ubus) | |||
205 | up(&mon_lock); | 206 | up(&mon_lock); |
206 | } | 207 | } |
207 | 208 | ||
209 | static int mon_notify(struct notifier_block *self, unsigned long action, | ||
210 | void *dev) | ||
211 | { | ||
212 | switch (action) { | ||
213 | case USB_BUS_ADD: | ||
214 | mon_bus_add(dev); | ||
215 | break; | ||
216 | case USB_BUS_REMOVE: | ||
217 | mon_bus_remove(dev); | ||
218 | } | ||
219 | return NOTIFY_OK; | ||
220 | } | ||
221 | |||
222 | static struct notifier_block mon_nb = { | ||
223 | .notifier_call = mon_notify, | ||
224 | }; | ||
225 | |||
208 | /* | 226 | /* |
209 | * Ops | 227 | * Ops |
210 | */ | 228 | */ |
@@ -212,8 +230,6 @@ static struct usb_mon_operations mon_ops_0 = { | |||
212 | .urb_submit = mon_submit, | 230 | .urb_submit = mon_submit, |
213 | .urb_submit_error = mon_submit_error, | 231 | .urb_submit_error = mon_submit_error, |
214 | .urb_complete = mon_complete, | 232 | .urb_complete = mon_complete, |
215 | .bus_add = mon_bus_add, | ||
216 | .bus_remove = mon_bus_remove, | ||
217 | }; | 233 | }; |
218 | 234 | ||
219 | /* | 235 | /* |
@@ -329,6 +345,8 @@ static int __init mon_init(void) | |||
329 | } | 345 | } |
330 | // MOD_INC_USE_COUNT(which_module?); | 346 | // MOD_INC_USE_COUNT(which_module?); |
331 | 347 | ||
348 | usb_register_notify(&mon_nb); | ||
349 | |||
332 | down(&usb_bus_list_lock); | 350 | down(&usb_bus_list_lock); |
333 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { | 351 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { |
334 | mon_bus_init(mondir, ubus); | 352 | mon_bus_init(mondir, ubus); |
@@ -342,6 +360,7 @@ static void __exit mon_exit(void) | |||
342 | struct mon_bus *mbus; | 360 | struct mon_bus *mbus; |
343 | struct list_head *p; | 361 | struct list_head *p; |
344 | 362 | ||
363 | usb_unregister_notify(&mon_nb); | ||
345 | usb_mon_deregister(); | 364 | usb_mon_deregister(); |
346 | 365 | ||
347 | down(&mon_lock); | 366 | down(&mon_lock); |
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index 8c010bb44eb8..efd6ca7e4ac5 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig | |||
@@ -294,7 +294,7 @@ config USB_NET_ZAURUS | |||
294 | This also supports some related device firmware, as used in some | 294 | This also supports some related device firmware, as used in some |
295 | PDAs from Olympus and some cell phones from Motorola. | 295 | PDAs from Olympus and some cell phones from Motorola. |
296 | 296 | ||
297 | If you install an alternate ROM image, such as the Linux 2.6 based | 297 | If you install an alternate image, such as the Linux 2.6 based |
298 | versions of OpenZaurus, you should no longer need to support this | 298 | versions of OpenZaurus, you should no longer need to support this |
299 | protocol. Only the "eth-fd" or "net_fd" drivers in these devices | 299 | protocol. Only the "eth-fd" or "net_fd" drivers in these devices |
300 | really need this non-conformant variant of CDC Ethernet (or in | 300 | really need this non-conformant variant of CDC Ethernet (or in |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index c82655d3d448..6bef1be6b36c 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -469,7 +469,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) | |||
469 | 0, | 469 | 0, |
470 | KAWETH_CONTROL_TIMEOUT); | 470 | KAWETH_CONTROL_TIMEOUT); |
471 | 471 | ||
472 | udelay(10000); | 472 | mdelay(10); |
473 | 473 | ||
474 | kaweth_dbg("kaweth_reset() returns %d.",result); | 474 | kaweth_dbg("kaweth_reset() returns %d.",result); |
475 | 475 | ||
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 6a4ffe6c3977..537eb181d985 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -1384,7 +1384,6 @@ static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) | |||
1384 | usb_kill_urb(pegasus->rx_urb); | 1384 | usb_kill_urb(pegasus->rx_urb); |
1385 | usb_kill_urb(pegasus->intr_urb); | 1385 | usb_kill_urb(pegasus->intr_urb); |
1386 | } | 1386 | } |
1387 | intf->dev.power.power_state = PMSG_SUSPEND; | ||
1388 | return 0; | 1387 | return 0; |
1389 | } | 1388 | } |
1390 | 1389 | ||
@@ -1392,7 +1391,6 @@ static int pegasus_resume (struct usb_interface *intf) | |||
1392 | { | 1391 | { |
1393 | struct pegasus *pegasus = usb_get_intfdata(intf); | 1392 | struct pegasus *pegasus = usb_get_intfdata(intf); |
1394 | 1393 | ||
1395 | intf->dev.power.power_state = PMSG_ON; | ||
1396 | netif_device_attach (pegasus->net); | 1394 | netif_device_attach (pegasus->net); |
1397 | if (netif_running(pegasus->net)) { | 1395 | if (netif_running(pegasus->net)) { |
1398 | pegasus->rx_urb->status = 0; | 1396 | pegasus->rx_urb->status = 0; |
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index b98f2a833442..9fbd59b55cb6 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h | |||
@@ -181,6 +181,8 @@ PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, | |||
181 | DEFAULT_GPIO_RESET ) | 181 | DEFAULT_GPIO_RESET ) |
182 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, | 182 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, |
183 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 183 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
184 | PEGASUS_DEV( "Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004, | ||
185 | DEFAULT_GPIO_RESET | PEGASUS_II ) | ||
184 | PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", | 186 | PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", |
185 | VENDOR_ADMTEK, 0x8511, | 187 | VENDOR_ADMTEK, 0x8511, |
186 | DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) | 188 | DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA ) |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index c3d4e3589e30..787dd3591d6a 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -909,6 +909,7 @@ static void rtl8150_disconnect(struct usb_interface *intf) | |||
909 | usb_set_intfdata(intf, NULL); | 909 | usb_set_intfdata(intf, NULL); |
910 | if (dev) { | 910 | if (dev) { |
911 | set_bit(RTL8150_UNPLUG, &dev->flags); | 911 | set_bit(RTL8150_UNPLUG, &dev->flags); |
912 | tasklet_disable(&dev->tl); | ||
912 | unregister_netdev(dev->netdev); | 913 | unregister_netdev(dev->netdev); |
913 | unlink_all_urbs(dev); | 914 | unlink_all_urbs(dev); |
914 | free_all_urbs(dev); | 915 | free_all_urbs(dev); |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index fce81d738933..74f05c9c84d5 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -1185,7 +1185,6 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) | |||
1185 | netif_device_detach (dev->net); | 1185 | netif_device_detach (dev->net); |
1186 | (void) unlink_urbs (dev, &dev->rxq); | 1186 | (void) unlink_urbs (dev, &dev->rxq); |
1187 | (void) unlink_urbs (dev, &dev->txq); | 1187 | (void) unlink_urbs (dev, &dev->txq); |
1188 | intf->dev.power.power_state = PMSG_SUSPEND; | ||
1189 | return 0; | 1188 | return 0; |
1190 | } | 1189 | } |
1191 | EXPORT_SYMBOL_GPL(usbnet_suspend); | 1190 | EXPORT_SYMBOL_GPL(usbnet_suspend); |
@@ -1194,7 +1193,6 @@ int usbnet_resume (struct usb_interface *intf) | |||
1194 | { | 1193 | { |
1195 | struct usbnet *dev = usb_get_intfdata(intf); | 1194 | struct usbnet *dev = usb_get_intfdata(intf); |
1196 | 1195 | ||
1197 | intf->dev.power.power_state = PMSG_ON; | ||
1198 | netif_device_attach (dev->net); | 1196 | netif_device_attach (dev->net); |
1199 | tasklet_schedule (&dev->bh); | 1197 | tasklet_schedule (&dev->bh); |
1200 | return 0; | 1198 | return 0; |
diff --git a/drivers/usb/serial/ChangeLog.old b/drivers/usb/serial/ChangeLog.old new file mode 100644 index 000000000000..c1b279939bbf --- /dev/null +++ b/drivers/usb/serial/ChangeLog.old | |||
@@ -0,0 +1,730 @@ | |||
1 | This is the contents of some of the drivers/usb/serial/ files that had old | ||
2 | changelog comments. They were quite old, and out of date, and we don't keep | ||
3 | them anymore, so I've put them here, away from the source files, in case | ||
4 | people still care to see them. | ||
5 | |||
6 | - Greg Kroah-Hartman <greg@kroah.com> October 20, 2005 | ||
7 | |||
8 | ----------------------------------------------------------------------- | ||
9 | usb-serial.h Change Log comments: | ||
10 | |||
11 | (03/26/2002) gkh | ||
12 | removed the port->tty check from port_paranoia_check() due to serial | ||
13 | consoles not having a tty device assigned to them. | ||
14 | |||
15 | (12/03/2001) gkh | ||
16 | removed active from the port structure. | ||
17 | added documentation to the usb_serial_device_type structure | ||
18 | |||
19 | (10/10/2001) gkh | ||
20 | added vendor and product to serial structure. Needed to determine device | ||
21 | owner when the device is disconnected. | ||
22 | |||
23 | (05/30/2001) gkh | ||
24 | added sem to port structure and removed port_lock | ||
25 | |||
26 | (10/05/2000) gkh | ||
27 | Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help | ||
28 | fix bug with urb->dev not being set properly, now that the usb core | ||
29 | needs it. | ||
30 | |||
31 | (09/11/2000) gkh | ||
32 | Added usb_serial_debug_data function to help get rid of #DEBUG in the | ||
33 | drivers. | ||
34 | |||
35 | (08/28/2000) gkh | ||
36 | Added port_lock to port structure. | ||
37 | |||
38 | (08/08/2000) gkh | ||
39 | Added open_count to port structure. | ||
40 | |||
41 | (07/23/2000) gkh | ||
42 | Added bulk_out_endpointAddress to port structure. | ||
43 | |||
44 | (07/19/2000) gkh, pberger, and borchers | ||
45 | Modifications to allow usb-serial drivers to be modules. | ||
46 | |||
47 | ----------------------------------------------------------------------- | ||
48 | usb-serial.c Change Log comments: | ||
49 | |||
50 | (12/10/2002) gkh | ||
51 | Split the ports off into their own struct device, and added a | ||
52 | usb-serial bus driver. | ||
53 | |||
54 | (11/19/2002) gkh | ||
55 | removed a few #ifdefs for the generic code and cleaned up the failure | ||
56 | logic in initialization. | ||
57 | |||
58 | (10/02/2002) gkh | ||
59 | moved the console code to console.c and out of this file. | ||
60 | |||
61 | (06/05/2002) gkh | ||
62 | moved location of startup() call in serial_probe() until after all | ||
63 | of the port information and endpoints are initialized. This makes | ||
64 | things easier for some drivers. | ||
65 | |||
66 | (04/10/2002) gkh | ||
67 | added serial_read_proc function which creates a | ||
68 | /proc/tty/driver/usb-serial file. | ||
69 | |||
70 | (03/27/2002) gkh | ||
71 | Got USB serial console code working properly and merged into the main | ||
72 | version of the tree. Thanks to Randy Dunlap for the initial version | ||
73 | of this code, and for pushing me to finish it up. | ||
74 | The USB serial console works with any usb serial driver device. | ||
75 | |||
76 | (03/21/2002) gkh | ||
77 | Moved all manipulation of port->open_count into the core. Now the | ||
78 | individual driver's open and close functions are called only when the | ||
79 | first open() and last close() is called. Making the drivers a bit | ||
80 | smaller and simpler. | ||
81 | Fixed a bug if a driver didn't have the owner field set. | ||
82 | |||
83 | (02/26/2002) gkh | ||
84 | Moved all locking into the main serial_* functions, instead of having | ||
85 | the individual drivers have to grab the port semaphore. This should | ||
86 | reduce races. | ||
87 | Reworked the MOD_INC logic a bit to always increment and decrement, even | ||
88 | if the generic driver is being used. | ||
89 | |||
90 | (10/10/2001) gkh | ||
91 | usb_serial_disconnect() now sets the serial->dev pointer is to NULL to | ||
92 | help prevent child drivers from accessing the device since it is now | ||
93 | gone. | ||
94 | |||
95 | (09/13/2001) gkh | ||
96 | Moved generic driver initialize after we have registered with the USB | ||
97 | core. Thanks to Randy Dunlap for pointing this problem out. | ||
98 | |||
99 | (07/03/2001) gkh | ||
100 | Fixed module paramater size. Thanks to John Brockmeyer for the pointer. | ||
101 | Fixed vendor and product getting defined through the MODULE_PARM macro | ||
102 | if the Generic driver wasn't compiled in. | ||
103 | Fixed problem with generic_shutdown() not being called for drivers that | ||
104 | don't have a shutdown() function. | ||
105 | |||
106 | (06/06/2001) gkh | ||
107 | added evil hack that is needed for the prolific pl2303 device due to the | ||
108 | crazy way its endpoints are set up. | ||
109 | |||
110 | (05/30/2001) gkh | ||
111 | switched from using spinlock to a semaphore, which fixes lots of problems. | ||
112 | |||
113 | (04/08/2001) gb | ||
114 | Identify version on module load. | ||
115 | |||
116 | 2001_02_05 gkh | ||
117 | Fixed buffer overflows bug with the generic serial driver. Thanks to | ||
118 | Todd Squires <squirest@ct0.com> for fixing this. | ||
119 | |||
120 | (01/10/2001) gkh | ||
121 | Fixed bug where the generic serial adaptor grabbed _any_ device that was | ||
122 | offered to it. | ||
123 | |||
124 | (12/12/2000) gkh | ||
125 | Removed MOD_INC and MOD_DEC from poll and disconnect functions, and | ||
126 | moved them to the serial_open and serial_close functions. | ||
127 | Also fixed bug with there not being a MOD_DEC for the generic driver | ||
128 | (thanks to Gary Brubaker for finding this.) | ||
129 | |||
130 | (11/29/2000) gkh | ||
131 | Small NULL pointer initialization cleanup which saves a bit of disk image | ||
132 | |||
133 | (11/01/2000) Adam J. Richter | ||
134 | instead of using idVendor/idProduct pairs, usb serial drivers | ||
135 | now identify their hardware interest with usb_device_id tables, | ||
136 | which they usually have anyhow for use with MODULE_DEVICE_TABLE. | ||
137 | |||
138 | (10/05/2000) gkh | ||
139 | Fixed bug with urb->dev not being set properly, now that the usb | ||
140 | core needs it. | ||
141 | |||
142 | (09/11/2000) gkh | ||
143 | Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
144 | |||
145 | (08/28/2000) gkh | ||
146 | Added port_lock to port structure. | ||
147 | Added locks for SMP safeness to generic driver | ||
148 | Fixed the ability to open a generic device's port more than once. | ||
149 | |||
150 | (07/23/2000) gkh | ||
151 | Added bulk_out_endpointAddress to port structure. | ||
152 | |||
153 | (07/19/2000) gkh, pberger, and borchers | ||
154 | Modifications to allow usb-serial drivers to be modules. | ||
155 | |||
156 | (07/03/2000) gkh | ||
157 | Added more debugging to serial_ioctl call | ||
158 | |||
159 | (06/25/2000) gkh | ||
160 | Changed generic_write_bulk_callback to not call wake_up_interruptible | ||
161 | directly, but to have port_softint do it at a safer time. | ||
162 | |||
163 | (06/23/2000) gkh | ||
164 | Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
165 | |||
166 | (05/22/2000) gkh | ||
167 | Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be | ||
168 | removed from the individual device source files. | ||
169 | |||
170 | (05/03/2000) gkh | ||
171 | Added the Digi Acceleport driver from Al Borchers and Peter Berger. | ||
172 | |||
173 | (05/02/2000) gkh | ||
174 | Changed devfs and tty register code to work properly now. This was based on | ||
175 | the ACM driver changes by Vojtech Pavlik. | ||
176 | |||
177 | (04/27/2000) Ryan VanderBijl | ||
178 | Put calls to *_paranoia_checks into one function. | ||
179 | |||
180 | (04/23/2000) gkh | ||
181 | Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. | ||
182 | Moved when the startup code printed out the devices that are supported. | ||
183 | |||
184 | (04/19/2000) gkh | ||
185 | Added driver for ZyXEL omni.net lcd plus ISDN TA | ||
186 | Made startup info message specify which drivers were compiled in. | ||
187 | |||
188 | (04/03/2000) gkh | ||
189 | Changed the probe process to remove the module unload races. | ||
190 | Changed where the tty layer gets initialized to have devfs work nicer. | ||
191 | Added initial devfs support. | ||
192 | |||
193 | (03/26/2000) gkh | ||
194 | Split driver up into device specific pieces. | ||
195 | |||
196 | (03/19/2000) gkh | ||
197 | Fixed oops that could happen when device was removed while a program | ||
198 | was talking to the device. | ||
199 | Removed the static urbs and now all urbs are created and destroyed | ||
200 | dynamically. | ||
201 | Reworked the internal interface. Now everything is based on the | ||
202 | usb_serial_port structure instead of the larger usb_serial structure. | ||
203 | This fixes the bug that a multiport device could not have more than | ||
204 | one port open at one time. | ||
205 | |||
206 | (03/17/2000) gkh | ||
207 | Added config option for debugging messages. | ||
208 | Added patch for keyspan pda from Brian Warner. | ||
209 | |||
210 | (03/06/2000) gkh | ||
211 | Added the keyspan pda code from Brian Warner <warner@lothar.com> | ||
212 | Moved a bunch of the port specific stuff into its own structure. This | ||
213 | is in anticipation of the true multiport devices (there's a bug if you | ||
214 | try to access more than one port of any multiport device right now) | ||
215 | |||
216 | (02/21/2000) gkh | ||
217 | Made it so that any serial devices only have to specify which functions | ||
218 | they want to overload from the generic function calls (great, | ||
219 | inheritance in C, in a driver, just what I wanted...) | ||
220 | Added support for set_termios and ioctl function calls. No drivers take | ||
221 | advantage of this yet. | ||
222 | Removed the #ifdef MODULE, now there is no module specific code. | ||
223 | Cleaned up a few comments in usb-serial.h that were wrong (thanks again | ||
224 | to Miles Lott). | ||
225 | Small fix to get_free_serial. | ||
226 | |||
227 | (02/14/2000) gkh | ||
228 | Removed the Belkin and Peracom functionality from the driver due to | ||
229 | the lack of support from the vendor, and me not wanting people to | ||
230 | accidenatly buy the device, expecting it to work with Linux. | ||
231 | Added read_bulk_callback and write_bulk_callback to the type structure | ||
232 | for the needs of the FTDI and WhiteHEAT driver. | ||
233 | Changed all reverences to FTDI to FTDI_SIO at the request of Bill | ||
234 | Ryder. | ||
235 | Changed the output urb size back to the max endpoint size to make | ||
236 | the ftdi_sio driver have it easier, and due to the fact that it didn't | ||
237 | really increase the speed any. | ||
238 | |||
239 | (02/11/2000) gkh | ||
240 | Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a | ||
241 | patch from Miles Lott (milos@insync.net). | ||
242 | Fixed bug with not restoring the minor range that a device grabs, if | ||
243 | the startup function fails (thanks Miles for finding this). | ||
244 | |||
245 | (02/05/2000) gkh | ||
246 | Added initial framework for the Keyspan PDA serial converter so that | ||
247 | Brian Warner has a place to put his code. | ||
248 | Made the ezusb specific functions generic enough that different | ||
249 | devices can use them (whiteheat and keyspan_pda both need them). | ||
250 | Split out a whole bunch of structure and other stuff to a separate | ||
251 | usb-serial.h file. | ||
252 | Made the Visor connection messages a little more understandable, now | ||
253 | that Miles Lott (milos@insync.net) has gotten the Generic channel to | ||
254 | work. Also made them always show up in the log file. | ||
255 | |||
256 | (01/25/2000) gkh | ||
257 | Added initial framework for FTDI serial converter so that Bill Ryder | ||
258 | has a place to put his code. | ||
259 | Added the vendor specific info from Handspring. Now we can print out | ||
260 | informational debug messages as well as understand what is happening. | ||
261 | |||
262 | (01/23/2000) gkh | ||
263 | Fixed problem of crash when trying to open a port that didn't have a | ||
264 | device assigned to it. Made the minor node finding a little smarter, | ||
265 | now it looks to find a continuous space for the new device. | ||
266 | |||
267 | (01/21/2000) gkh | ||
268 | Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) | ||
269 | Fixed get_serial_by_minor which was all messed up for multi port | ||
270 | devices. Fixed multi port problem for generic devices. Now the number | ||
271 | of ports is determined by the number of bulk out endpoints for the | ||
272 | generic device. | ||
273 | |||
274 | (01/19/2000) gkh | ||
275 | Removed lots of cruft that was around from the old (pre urb) driver | ||
276 | interface. | ||
277 | Made the serial_table dynamic. This should save lots of memory when | ||
278 | the number of minor nodes goes up to 256. | ||
279 | Added initial support for devices that have more than one port. | ||
280 | Added more debugging comments for the Visor, and added a needed | ||
281 | set_configuration call. | ||
282 | |||
283 | (01/17/2000) gkh | ||
284 | Fixed the WhiteHEAT firmware (my processing tool had a bug) | ||
285 | and added new debug loader firmware for it. | ||
286 | Removed the put_char function as it isn't really needed. | ||
287 | Added visor startup commands as found by the Win98 dump. | ||
288 | |||
289 | (01/13/2000) gkh | ||
290 | Fixed the vendor id for the generic driver to the one I meant it to be. | ||
291 | |||
292 | (01/12/2000) gkh | ||
293 | Forget the version numbering...that's pretty useless... | ||
294 | Made the driver able to be compiled so that the user can select which | ||
295 | converter they want to use. This allows people who only want the Visor | ||
296 | support to not pay the memory size price of the WhiteHEAT. | ||
297 | Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) | ||
298 | grabbed the root hub. Not good. | ||
299 | |||
300 | version 0.4.0 (01/10/2000) gkh | ||
301 | Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT | ||
302 | device. Added startup function to allow firmware to be downloaded to | ||
303 | a device if it needs to be. | ||
304 | Added firmware download logic to the WhiteHEAT device. | ||
305 | Started to add #defines to split up the different drivers for potential | ||
306 | configuration option. | ||
307 | |||
308 | version 0.3.1 (12/30/99) gkh | ||
309 | Fixed problems with urb for bulk out. | ||
310 | Added initial support for multiple sets of endpoints. This enables | ||
311 | the Handspring Visor to be attached successfully. Only the first | ||
312 | bulk in / bulk out endpoint pair is being used right now. | ||
313 | |||
314 | version 0.3.0 (12/27/99) gkh | ||
315 | Added initial support for the Handspring Visor based on a patch from | ||
316 | Miles Lott (milos@sneety.insync.net) | ||
317 | Cleaned up the code a bunch and converted over to using urbs only. | ||
318 | |||
319 | version 0.2.3 (12/21/99) gkh | ||
320 | Added initial support for the Connect Tech WhiteHEAT converter. | ||
321 | Incremented the number of ports in expectation of getting the | ||
322 | WhiteHEAT to work properly (4 ports per connection). | ||
323 | Added notification on insertion and removal of what port the | ||
324 | device is/was connected to (and what kind of device it was). | ||
325 | |||
326 | version 0.2.2 (12/16/99) gkh | ||
327 | Changed major number to the new allocated number. We're legal now! | ||
328 | |||
329 | version 0.2.1 (12/14/99) gkh | ||
330 | Fixed bug that happens when device node is opened when there isn't a | ||
331 | device attached to it. Thanks to marek@webdesign.no for noticing this. | ||
332 | |||
333 | version 0.2.0 (11/10/99) gkh | ||
334 | Split up internals to make it easier to add different types of serial | ||
335 | converters to the code. | ||
336 | Added a "generic" driver that gets it's vendor and product id | ||
337 | from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) | ||
338 | for the idea and sample code (from the usb scanner driver.) | ||
339 | Cleared up any licensing questions by releasing it under the GNU GPL. | ||
340 | |||
341 | version 0.1.2 (10/25/99) gkh | ||
342 | Fixed bug in detecting device. | ||
343 | |||
344 | version 0.1.1 (10/05/99) gkh | ||
345 | Changed the major number to not conflict with anything else. | ||
346 | |||
347 | version 0.1 (09/28/99) gkh | ||
348 | Can recognize the two different devices and start up a read from | ||
349 | device when asked to. Writes also work. No control signals yet, this | ||
350 | all is vendor specific data (i.e. no spec), also no control for | ||
351 | different baud rates or other bit settings. | ||
352 | Currently we are using the same devid as the acm driver. This needs | ||
353 | to change. | ||
354 | |||
355 | ----------------------------------------------------------------------- | ||
356 | visor.c Change Log comments: | ||
357 | |||
358 | (06/03/2003) Judd Montgomery <judd at jpilot.org> | ||
359 | Added support for module parameter options for untested/unknown | ||
360 | devices. | ||
361 | |||
362 | (03/09/2003) gkh | ||
363 | Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl | ||
364 | <brachtl@redgrep.cz> for the information. | ||
365 | |||
366 | (03/05/2003) gkh | ||
367 | Think Treo support is now working. | ||
368 | |||
369 | (04/03/2002) gkh | ||
370 | Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI | ||
371 | <hiro@zob.ne.jp> for the information. | ||
372 | |||
373 | (03/27/2002) gkh | ||
374 | Removed assumptions that port->tty was always valid (is not true | ||
375 | for usb serial console devices.) | ||
376 | |||
377 | (03/23/2002) gkh | ||
378 | Added support for the Palm i705 device, thanks to Thomas Riemer | ||
379 | <tom@netmech.com> for the information. | ||
380 | |||
381 | (03/21/2002) gkh | ||
382 | Added support for the Palm m130 device, thanks to Udo Eisenbarth | ||
383 | <udo.eisenbarth@web.de> for the information. | ||
384 | |||
385 | (02/27/2002) gkh | ||
386 | Reworked the urb handling logic. We have no more pool, but dynamically | ||
387 | allocate the urb and the transfer buffer on the fly. In testing this | ||
388 | does not incure any measurable overhead. This also relies on the fact | ||
389 | that we have proper reference counting logic for urbs. | ||
390 | |||
391 | (02/21/2002) SilaS | ||
392 | Added initial support for the Palm m515 devices. | ||
393 | |||
394 | (02/14/2002) gkh | ||
395 | Added support for the Clie S-360 device. | ||
396 | |||
397 | (12/18/2001) gkh | ||
398 | Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand | ||
399 | for the patch. | ||
400 | |||
401 | (11/11/2001) gkh | ||
402 | Added support for the m125 devices, and added check to prevent oopses | ||
403 | for Clié devices that lie about the number of ports they have. | ||
404 | |||
405 | (08/30/2001) gkh | ||
406 | Added support for the Clie devices, both the 3.5 and 4.0 os versions. | ||
407 | Many thanks to Daniel Burke, and Bryan Payne for helping with this. | ||
408 | |||
409 | (08/23/2001) gkh | ||
410 | fixed a few potential bugs pointed out by Oliver Neukum. | ||
411 | |||
412 | (05/30/2001) gkh | ||
413 | switched from using spinlock to a semaphore, which fixes lots of problems. | ||
414 | |||
415 | (05/28/2000) gkh | ||
416 | Added initial support for the Palm m500 and Palm m505 devices. | ||
417 | |||
418 | (04/08/2001) gb | ||
419 | Identify version on module load. | ||
420 | |||
421 | (01/21/2000) gkh | ||
422 | Added write_room and chars_in_buffer, as they were previously using the | ||
423 | generic driver versions which is all wrong now that we are using an urb | ||
424 | pool. Thanks to Wolfgang Grandegger for pointing this out to me. | ||
425 | Removed count assignment in the write function, which was not needed anymore | ||
426 | either. Thanks to Al Borchers for pointing this out. | ||
427 | |||
428 | (12/12/2000) gkh | ||
429 | Moved MOD_DEC to end of visor_close to be nicer, as the final write | ||
430 | message can sleep. | ||
431 | |||
432 | (11/12/2000) gkh | ||
433 | Fixed bug with data being dropped on the floor by forcing tty->low_latency | ||
434 | to be on. Hopefully this fixes the OHCI issue! | ||
435 | |||
436 | (11/01/2000) Adam J. Richter | ||
437 | usb_device_id table support | ||
438 | |||
439 | (10/05/2000) gkh | ||
440 | Fixed bug with urb->dev not being set properly, now that the usb | ||
441 | core needs it. | ||
442 | |||
443 | (09/11/2000) gkh | ||
444 | Got rid of always calling kmalloc for every urb we wrote out to the | ||
445 | device. | ||
446 | Added visor_read_callback so we can keep track of bytes in and out for | ||
447 | those people who like to know the speed of their device. | ||
448 | Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
449 | |||
450 | (09/06/2000) gkh | ||
451 | Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_ | ||
452 | the host controller drivers set urb->dev = NULL when the urb is finished. | ||
453 | |||
454 | (08/28/2000) gkh | ||
455 | Added locks for SMP safeness. | ||
456 | |||
457 | (08/08/2000) gkh | ||
458 | Fixed endian problem in visor_startup. | ||
459 | Fixed MOD_INC and MOD_DEC logic and the ability to open a port more | ||
460 | than once. | ||
461 | |||
462 | (07/23/2000) gkh | ||
463 | Added pool of write urbs to speed up transfers to the visor. | ||
464 | |||
465 | (07/19/2000) gkh | ||
466 | Added module_init and module_exit functions to handle the fact that this | ||
467 | driver is a loadable module now. | ||
468 | |||
469 | (07/03/2000) gkh | ||
470 | Added visor_set_ioctl and visor_set_termios functions (they don't do much | ||
471 | of anything, but are good for debugging.) | ||
472 | |||
473 | (06/25/2000) gkh | ||
474 | Fixed bug in visor_unthrottle that should help with the disconnect in PPP | ||
475 | bug that people have been reporting. | ||
476 | |||
477 | (06/23/2000) gkh | ||
478 | Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
479 | |||
480 | (04/27/2000) Ryan VanderBijl | ||
481 | Fixed memory leak in visor_close | ||
482 | |||
483 | (03/26/2000) gkh | ||
484 | Split driver up into device specific pieces. | ||
485 | |||
486 | ----------------------------------------------------------------------- | ||
487 | pl2303.c Change Log comments: | ||
488 | |||
489 | 2002_Mar_26 gkh | ||
490 | allowed driver to work properly if there is no tty assigned to a port | ||
491 | (this happens for serial console devices.) | ||
492 | |||
493 | 2001_Oct_06 gkh | ||
494 | Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it. | ||
495 | |||
496 | 2001_Sep_19 gkh | ||
497 | Added break support. | ||
498 | |||
499 | 2001_Aug_30 gkh | ||
500 | fixed oops in write_bulk_callback. | ||
501 | |||
502 | 2001_Aug_28 gkh | ||
503 | reworked buffer logic to be like other usb-serial drivers. Hopefully | ||
504 | removing some reported problems. | ||
505 | |||
506 | 2001_Jun_06 gkh | ||
507 | finished porting to 2.4 format. | ||
508 | |||
509 | |||
510 | ----------------------------------------------------------------------- | ||
511 | io_edgeport.c Change Log comments: | ||
512 | |||
513 | 2003_04_03 al borchers | ||
514 | - fixed a bug (that shows up with dosemu) where the tty struct is | ||
515 | used in a callback after it has been freed | ||
516 | |||
517 | 2.3 2002_03_08 greg kroah-hartman | ||
518 | - fixed bug when multiple devices were attached at the same time. | ||
519 | |||
520 | 2.2 2001_11_14 greg kroah-hartman | ||
521 | - fixed bug in edge_close that kept the port from being used more | ||
522 | than once. | ||
523 | - fixed memory leak on device removal. | ||
524 | - fixed potential double free of memory when command urb submitting | ||
525 | failed. | ||
526 | - other small cleanups when the device is removed | ||
527 | |||
528 | 2.1 2001_07_09 greg kroah-hartman | ||
529 | - added support for TIOCMBIS and TIOCMBIC. | ||
530 | |||
531 | (04/08/2001) gb | ||
532 | - Identify version on module load. | ||
533 | |||
534 | 2.0 2001_03_05 greg kroah-hartman | ||
535 | - reworked entire driver to fit properly in with the other usb-serial | ||
536 | drivers. Occasional oopses still happen, but it's a good start. | ||
537 | |||
538 | 1.2.3 (02/23/2001) greg kroah-hartman | ||
539 | - changed device table to work properly for 2.4.x final format. | ||
540 | - fixed problem with dropping data at high data rates. | ||
541 | |||
542 | 1.2.2 (11/27/2000) greg kroah-hartman | ||
543 | - cleaned up more NTisms. | ||
544 | - Added device table for 2.4.0-test11 | ||
545 | |||
546 | 1.2.1 (11/08/2000) greg kroah-hartman | ||
547 | - Started to clean up NTisms. | ||
548 | - Fixed problem with dev field of urb for kernels >= 2.4.0-test9 | ||
549 | |||
550 | 1.2 (10/17/2000) David Iacovelli | ||
551 | Remove all EPIC code and GPL source | ||
552 | Fix RELEVANT_IFLAG macro to include flow control | ||
553 | changes port configuration changes. | ||
554 | Fix redefinition of SERIAL_MAGIC | ||
555 | Change all timeout values to 5 seconds | ||
556 | Tried to fix the UHCI multiple urb submission, but failed miserably. | ||
557 | it seems to work fine with OHCI. | ||
558 | ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must | ||
559 | find a way to work arount this UHCI bug ) | ||
560 | |||
561 | 1.1 (10/11/2000) David Iacovelli | ||
562 | Fix XON/XOFF flow control to support both IXON and IXOFF | ||
563 | |||
564 | 0.9.27 (06/30/2000) David Iacovelli | ||
565 | Added transmit queue and now allocate urb for command writes. | ||
566 | |||
567 | 0.9.26 (06/29/2000) David Iacovelli | ||
568 | Add support for 80251 based edgeport | ||
569 | |||
570 | 0.9.25 (06/27/2000) David Iacovelli | ||
571 | Do not close the port if it has multiple opens. | ||
572 | |||
573 | 0.9.24 (05/26/2000) David Iacovelli | ||
574 | Add IOCTLs to support RXTX and JAVA POS | ||
575 | and first cut at running BlackBox Demo | ||
576 | |||
577 | 0.9.23 (05/24/2000) David Iacovelli | ||
578 | Add IOCTLs to support RXTX and JAVA POS | ||
579 | |||
580 | 0.9.22 (05/23/2000) David Iacovelli | ||
581 | fixed bug in enumeration. If epconfig turns on mapping by | ||
582 | path after a device is already plugged in, we now update | ||
583 | the mapping correctly | ||
584 | |||
585 | 0.9.21 (05/16/2000) David Iacovelli | ||
586 | Added BlockUntilChaseResp() to also wait for txcredits | ||
587 | Updated the way we allocate and handle write URBs | ||
588 | Add debug code to dump buffers | ||
589 | |||
590 | 0.9.20 (05/01/2000) David Iacovelli | ||
591 | change driver to use usb/tts/ | ||
592 | |||
593 | 0.9.19 (05/01/2000) David Iacovelli | ||
594 | Update code to compile if DEBUG is off | ||
595 | |||
596 | 0.9.18 (04/28/2000) David Iacovelli | ||
597 | cleanup and test tty_register with devfs | ||
598 | |||
599 | 0.9.17 (04/27/2000) greg kroah-hartman | ||
600 | changed tty_register around to be like the way it | ||
601 | was before, but now it works properly with devfs. | ||
602 | |||
603 | 0.9.16 (04/26/2000) david iacovelli | ||
604 | Fixed bug in GetProductInfo() | ||
605 | |||
606 | 0.9.15 (04/25/2000) david iacovelli | ||
607 | Updated enumeration | ||
608 | |||
609 | 0.9.14 (04/24/2000) david iacovelli | ||
610 | Removed all config/status IOCTLS and | ||
611 | converted to using /proc/edgeport | ||
612 | still playing with devfs | ||
613 | |||
614 | 0.9.13 (04/24/2000) david iacovelli | ||
615 | Removed configuration based on ttyUSB0 | ||
616 | Added support for configuration using /prod/edgeport | ||
617 | first attempt at using devfs (not working yet!) | ||
618 | Added IOCTL to GetProductInfo() | ||
619 | Added support for custom baud rates | ||
620 | Add support for random port numbers | ||
621 | |||
622 | 0.9.12 (04/18/2000) david iacovelli | ||
623 | added additional configuration IOCTLs | ||
624 | use ttyUSB0 for configuration | ||
625 | |||
626 | 0.9.11 (04/17/2000) greg kroah-hartman | ||
627 | fixed module initialization race conditions. | ||
628 | made all urbs dynamically allocated. | ||
629 | made driver devfs compatible. now it only registers the tty device | ||
630 | when the device is actually plugged in. | ||
631 | |||
632 | 0.9.10 (04/13/2000) greg kroah-hartman | ||
633 | added proc interface framework. | ||
634 | |||
635 | 0.9.9 (04/13/2000) david iacovelli | ||
636 | added enumeration code and ioctls to configure the device | ||
637 | |||
638 | 0.9.8 (04/12/2000) david iacovelli | ||
639 | Change interrupt read start when device is plugged in | ||
640 | and stop when device is removed | ||
641 | process interrupt reads when all ports are closed | ||
642 | (keep value of rxBytesAvail consistent with the edgeport) | ||
643 | set the USB_BULK_QUEUE flag so that we can shove a bunch | ||
644 | of urbs at once down the pipe | ||
645 | |||
646 | 0.9.7 (04/10/2000) david iacovelli | ||
647 | start to add enumeration code. | ||
648 | generate serial number for epic devices | ||
649 | add support for kdb | ||
650 | |||
651 | 0.9.6 (03/30/2000) david iacovelli | ||
652 | add IOCTL to get string, manufacture, and boot descriptors | ||
653 | |||
654 | 0.9.5 (03/14/2000) greg kroah-hartman | ||
655 | more error checking added to SerialOpen to try to fix UHCI open problem | ||
656 | |||
657 | 0.9.4 (03/09/2000) greg kroah-hartman | ||
658 | added more error checking to handle oops when data is hanging | ||
659 | around and tty is abruptly closed. | ||
660 | |||
661 | 0.9.3 (03/09/2000) david iacovelli | ||
662 | Add epic support for xon/xoff chars | ||
663 | play with performance | ||
664 | |||
665 | 0.9.2 (03/08/2000) greg kroah-hartman | ||
666 | changed most "info" calls to "dbg" | ||
667 | implemented flow control properly in the termios call | ||
668 | |||
669 | 0.9.1 (03/08/2000) david iacovelli | ||
670 | added EPIC support | ||
671 | enabled bootloader update | ||
672 | |||
673 | 0.9 (03/08/2000) greg kroah-hartman | ||
674 | Release to IO networks. | ||
675 | Integrated changes that David made | ||
676 | made getting urbs for writing SMP safe | ||
677 | |||
678 | 0.8 (03/07/2000) greg kroah-hartman | ||
679 | Release to IO networks. | ||
680 | Fixed problems that were seen in code by David. | ||
681 | Now both Edgeport/4 and Edgeport/2 works properly. | ||
682 | Changed most of the functions to use port instead of serial. | ||
683 | |||
684 | 0.7 (02/27/2000) greg kroah-hartman | ||
685 | Milestone 3 release. | ||
686 | Release to IO Networks | ||
687 | ioctl for waiting on line change implemented. | ||
688 | ioctl for getting statistics implemented. | ||
689 | multiport support working. | ||
690 | lsr and msr registers are now handled properly. | ||
691 | change break now hooked up and working. | ||
692 | support for all known Edgeport devices. | ||
693 | |||
694 | 0.6 (02/22/2000) greg kroah-hartman | ||
695 | Release to IO networks. | ||
696 | CHASE is implemented correctly when port is closed. | ||
697 | SerialOpen now blocks correctly until port is fully opened. | ||
698 | |||
699 | 0.5 (02/20/2000) greg kroah-hartman | ||
700 | Release to IO networks. | ||
701 | Known problems: | ||
702 | modem status register changes are not sent on to the user | ||
703 | CHASE is not implemented when the port is closed. | ||
704 | |||
705 | 0.4 (02/16/2000) greg kroah-hartman | ||
706 | Second cut at the CeBit demo. | ||
707 | Doesn't leak memory on every write to the port | ||
708 | Still small leaks on startup. | ||
709 | Added support for Edgeport/2 and Edgeport/8 | ||
710 | |||
711 | 0.3 (02/15/2000) greg kroah-hartman | ||
712 | CeBit demo release. | ||
713 | Force the line settings to 4800, 8, 1, e for the demo. | ||
714 | Warning! This version leaks memory like crazy! | ||
715 | |||
716 | 0.2 (01/30/2000) greg kroah-hartman | ||
717 | Milestone 1 release. | ||
718 | Device is found by USB subsystem, enumerated, fimware is downloaded | ||
719 | and the descriptors are printed to the debug log, config is set, and | ||
720 | green light starts to blink. Open port works, and data can be sent | ||
721 | and received at the default settings of the UART. Loopback connector | ||
722 | and debug log confirms this. | ||
723 | |||
724 | 0.1 (01/23/2000) greg kroah-hartman | ||
725 | Initial release to help IO Networks try to set up their test system. | ||
726 | Edgeport4 is recognized, firmware is downloaded, config is set so | ||
727 | device blinks green light every 3 sec. Port is bound, but opening, | ||
728 | closing, and sending data do not work properly. | ||
729 | |||
730 | |||
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 9438909e87a5..7b5e8e4ee2bb 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -394,6 +394,15 @@ config USB_SERIAL_MCT_U232 | |||
394 | To compile this driver as a module, choose M here: the | 394 | To compile this driver as a module, choose M here: the |
395 | module will be called mct_u232. | 395 | module will be called mct_u232. |
396 | 396 | ||
397 | config USB_SERIAL_NOKIA_DKU2 | ||
398 | tristate "USB Nokia DKU2 Driver" | ||
399 | depends on USB_SERIAL | ||
400 | help | ||
401 | Say Y here if you want to use a Nokia DKU2 device. | ||
402 | |||
403 | To compile this driver as a module, choose M here: the | ||
404 | module will be called nokia_dku2. | ||
405 | |||
397 | config USB_SERIAL_PL2303 | 406 | config USB_SERIAL_PL2303 |
398 | tristate "USB Prolific 2303 Single Port Serial Driver" | 407 | tristate "USB Prolific 2303 Single Port Serial Driver" |
399 | depends on USB_SERIAL | 408 | depends on USB_SERIAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 6c7cdcc99a9e..55fd461793b7 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA) += keyspan_pda.o | |||
31 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o | 31 | obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o |
32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | 32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o |
33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
34 | obj-$(CONFIG_USB_SERIAL_NOKIA_DKU2) += nokia_dku2.o | ||
34 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 35 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
35 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 36 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
36 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 37 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 926d4c2c1600..1f29d8837327 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -30,9 +30,11 @@ static struct usb_driver airprime_driver = { | |||
30 | .id_table = id_table, | 30 | .id_table = id_table, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static struct usb_serial_device_type airprime_device = { | 33 | static struct usb_serial_driver airprime_device = { |
34 | .owner = THIS_MODULE, | 34 | .driver = { |
35 | .name = "airprime", | 35 | .owner = THIS_MODULE, |
36 | .name = "airprime", | ||
37 | }, | ||
36 | .id_table = id_table, | 38 | .id_table = id_table, |
37 | .num_interrupt_in = NUM_DONT_CARE, | 39 | .num_interrupt_in = NUM_DONT_CARE, |
38 | .num_bulk_in = NUM_DONT_CARE, | 40 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index abb1b2c543bb..84bc0ee4f061 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -121,10 +121,12 @@ static struct usb_driver belkin_driver = { | |||
121 | }; | 121 | }; |
122 | 122 | ||
123 | /* All of the device info needed for the serial converters */ | 123 | /* All of the device info needed for the serial converters */ |
124 | static struct usb_serial_device_type belkin_device = { | 124 | static struct usb_serial_driver belkin_device = { |
125 | .owner = THIS_MODULE, | 125 | .driver = { |
126 | .name = "Belkin / Peracom / GoHubs USB Serial Adapter", | 126 | .owner = THIS_MODULE, |
127 | .short_name = "belkin", | 127 | .name = "belkin", |
128 | }, | ||
129 | .description = "Belkin / Peracom / GoHubs USB Serial Adapter", | ||
128 | .id_table = id_table_combined, | 130 | .id_table = id_table_combined, |
129 | .num_interrupt_in = 1, | 131 | .num_interrupt_in = 1, |
130 | .num_bulk_in = 1, | 132 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 2f612c2d894b..664139afcfa9 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | static int usb_serial_device_match (struct device *dev, struct device_driver *drv) | 19 | static int usb_serial_device_match (struct device *dev, struct device_driver *drv) |
20 | { | 20 | { |
21 | struct usb_serial_device_type *driver; | 21 | struct usb_serial_driver *driver; |
22 | const struct usb_serial_port *port; | 22 | const struct usb_serial_port *port; |
23 | 23 | ||
24 | /* | 24 | /* |
@@ -44,7 +44,7 @@ struct bus_type usb_serial_bus_type = { | |||
44 | 44 | ||
45 | static int usb_serial_device_probe (struct device *dev) | 45 | static int usb_serial_device_probe (struct device *dev) |
46 | { | 46 | { |
47 | struct usb_serial_device_type *driver; | 47 | struct usb_serial_driver *driver; |
48 | struct usb_serial_port *port; | 48 | struct usb_serial_port *port; |
49 | int retval = 0; | 49 | int retval = 0; |
50 | int minor; | 50 | int minor; |
@@ -57,13 +57,13 @@ static int usb_serial_device_probe (struct device *dev) | |||
57 | 57 | ||
58 | driver = port->serial->type; | 58 | driver = port->serial->type; |
59 | if (driver->port_probe) { | 59 | if (driver->port_probe) { |
60 | if (!try_module_get(driver->owner)) { | 60 | if (!try_module_get(driver->driver.owner)) { |
61 | dev_err(dev, "module get failed, exiting\n"); | 61 | dev_err(dev, "module get failed, exiting\n"); |
62 | retval = -EIO; | 62 | retval = -EIO; |
63 | goto exit; | 63 | goto exit; |
64 | } | 64 | } |
65 | retval = driver->port_probe (port); | 65 | retval = driver->port_probe (port); |
66 | module_put(driver->owner); | 66 | module_put(driver->driver.owner); |
67 | if (retval) | 67 | if (retval) |
68 | goto exit; | 68 | goto exit; |
69 | } | 69 | } |
@@ -72,7 +72,7 @@ static int usb_serial_device_probe (struct device *dev) | |||
72 | tty_register_device (usb_serial_tty_driver, minor, dev); | 72 | tty_register_device (usb_serial_tty_driver, minor, dev); |
73 | dev_info(&port->serial->dev->dev, | 73 | dev_info(&port->serial->dev->dev, |
74 | "%s converter now attached to ttyUSB%d\n", | 74 | "%s converter now attached to ttyUSB%d\n", |
75 | driver->name, minor); | 75 | driver->description, minor); |
76 | 76 | ||
77 | exit: | 77 | exit: |
78 | return retval; | 78 | return retval; |
@@ -80,7 +80,7 @@ exit: | |||
80 | 80 | ||
81 | static int usb_serial_device_remove (struct device *dev) | 81 | static int usb_serial_device_remove (struct device *dev) |
82 | { | 82 | { |
83 | struct usb_serial_device_type *driver; | 83 | struct usb_serial_driver *driver; |
84 | struct usb_serial_port *port; | 84 | struct usb_serial_port *port; |
85 | int retval = 0; | 85 | int retval = 0; |
86 | int minor; | 86 | int minor; |
@@ -92,43 +92,38 @@ static int usb_serial_device_remove (struct device *dev) | |||
92 | 92 | ||
93 | driver = port->serial->type; | 93 | driver = port->serial->type; |
94 | if (driver->port_remove) { | 94 | if (driver->port_remove) { |
95 | if (!try_module_get(driver->owner)) { | 95 | if (!try_module_get(driver->driver.owner)) { |
96 | dev_err(dev, "module get failed, exiting\n"); | 96 | dev_err(dev, "module get failed, exiting\n"); |
97 | retval = -EIO; | 97 | retval = -EIO; |
98 | goto exit; | 98 | goto exit; |
99 | } | 99 | } |
100 | retval = driver->port_remove (port); | 100 | retval = driver->port_remove (port); |
101 | module_put(driver->owner); | 101 | module_put(driver->driver.owner); |
102 | } | 102 | } |
103 | exit: | 103 | exit: |
104 | minor = port->number; | 104 | minor = port->number; |
105 | tty_unregister_device (usb_serial_tty_driver, minor); | 105 | tty_unregister_device (usb_serial_tty_driver, minor); |
106 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", | 106 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", |
107 | driver->name, minor); | 107 | driver->description, minor); |
108 | 108 | ||
109 | return retval; | 109 | return retval; |
110 | } | 110 | } |
111 | 111 | ||
112 | int usb_serial_bus_register(struct usb_serial_device_type *device) | 112 | int usb_serial_bus_register(struct usb_serial_driver *driver) |
113 | { | 113 | { |
114 | int retval; | 114 | int retval; |
115 | 115 | ||
116 | if (device->short_name) | 116 | driver->driver.bus = &usb_serial_bus_type; |
117 | device->driver.name = (char *)device->short_name; | 117 | driver->driver.probe = usb_serial_device_probe; |
118 | else | 118 | driver->driver.remove = usb_serial_device_remove; |
119 | device->driver.name = (char *)device->name; | ||
120 | device->driver.bus = &usb_serial_bus_type; | ||
121 | device->driver.probe = usb_serial_device_probe; | ||
122 | device->driver.remove = usb_serial_device_remove; | ||
123 | device->driver.owner = device->owner; | ||
124 | 119 | ||
125 | retval = driver_register(&device->driver); | 120 | retval = driver_register(&driver->driver); |
126 | 121 | ||
127 | return retval; | 122 | return retval; |
128 | } | 123 | } |
129 | 124 | ||
130 | void usb_serial_bus_deregister(struct usb_serial_device_type *device) | 125 | void usb_serial_bus_deregister(struct usb_serial_driver *driver) |
131 | { | 126 | { |
132 | driver_unregister (&device->driver); | 127 | driver_unregister(&driver->driver); |
133 | } | 128 | } |
134 | 129 | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 97c78c21e8d1..c5334dd89b12 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -67,15 +67,17 @@ MODULE_DEVICE_TABLE (usb, id_table); | |||
67 | 67 | ||
68 | static struct usb_driver cp2101_driver = { | 68 | static struct usb_driver cp2101_driver = { |
69 | .owner = THIS_MODULE, | 69 | .owner = THIS_MODULE, |
70 | .name = "CP2101", | 70 | .name = "cp2101", |
71 | .probe = usb_serial_probe, | 71 | .probe = usb_serial_probe, |
72 | .disconnect = usb_serial_disconnect, | 72 | .disconnect = usb_serial_disconnect, |
73 | .id_table = id_table, | 73 | .id_table = id_table, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static struct usb_serial_device_type cp2101_device = { | 76 | static struct usb_serial_driver cp2101_device = { |
77 | .owner = THIS_MODULE, | 77 | .driver = { |
78 | .name = "CP2101", | 78 | .owner = THIS_MODULE, |
79 | .name = "cp2101", | ||
80 | }, | ||
79 | .id_table = id_table, | 81 | .id_table = id_table, |
80 | .num_interrupt_in = 0, | 82 | .num_interrupt_in = 0, |
81 | .num_bulk_in = 0, | 83 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index b5b431067b08..e581e4ae8483 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -83,10 +83,12 @@ static struct usb_driver cyberjack_driver = { | |||
83 | .id_table = id_table, | 83 | .id_table = id_table, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static struct usb_serial_device_type cyberjack_device = { | 86 | static struct usb_serial_driver cyberjack_device = { |
87 | .owner = THIS_MODULE, | 87 | .driver = { |
88 | .name = "Reiner SCT Cyberjack USB card reader", | 88 | .owner = THIS_MODULE, |
89 | .short_name = "cyberjack", | 89 | .name = "cyberjack", |
90 | }, | ||
91 | .description = "Reiner SCT Cyberjack USB card reader", | ||
90 | .id_table = id_table, | 92 | .id_table = id_table, |
91 | .num_interrupt_in = 1, | 93 | .num_interrupt_in = 1, |
92 | .num_bulk_in = 1, | 94 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9ee1aaff2fcd..af9290ed257b 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -176,10 +176,12 @@ static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf, u | |||
176 | static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count); | 176 | static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count); |
177 | 177 | ||
178 | 178 | ||
179 | static struct usb_serial_device_type cypress_earthmate_device = { | 179 | static struct usb_serial_driver cypress_earthmate_device = { |
180 | .owner = THIS_MODULE, | 180 | .driver = { |
181 | .name = "DeLorme Earthmate USB", | 181 | .owner = THIS_MODULE, |
182 | .short_name = "earthmate", | 182 | .name = "earthmate", |
183 | }, | ||
184 | .description = "DeLorme Earthmate USB", | ||
183 | .id_table = id_table_earthmate, | 185 | .id_table = id_table_earthmate, |
184 | .num_interrupt_in = 1, | 186 | .num_interrupt_in = 1, |
185 | .num_interrupt_out = 1, | 187 | .num_interrupt_out = 1, |
@@ -203,10 +205,12 @@ static struct usb_serial_device_type cypress_earthmate_device = { | |||
203 | .write_int_callback = cypress_write_int_callback, | 205 | .write_int_callback = cypress_write_int_callback, |
204 | }; | 206 | }; |
205 | 207 | ||
206 | static struct usb_serial_device_type cypress_hidcom_device = { | 208 | static struct usb_serial_driver cypress_hidcom_device = { |
207 | .owner = THIS_MODULE, | 209 | .driver = { |
208 | .name = "HID->COM RS232 Adapter", | 210 | .owner = THIS_MODULE, |
209 | .short_name = "cyphidcom", | 211 | .name = "cyphidcom", |
212 | }, | ||
213 | .description = "HID->COM RS232 Adapter", | ||
210 | .id_table = id_table_cyphidcomrs232, | 214 | .id_table = id_table_cyphidcomrs232, |
211 | .num_interrupt_in = 1, | 215 | .num_interrupt_in = 1, |
212 | .num_interrupt_out = 1, | 216 | .num_interrupt_out = 1, |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index a19a47f6cf12..dc74644a603d 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -503,10 +503,12 @@ static struct usb_driver digi_driver = { | |||
503 | 503 | ||
504 | /* device info needed for the Digi serial converter */ | 504 | /* device info needed for the Digi serial converter */ |
505 | 505 | ||
506 | static struct usb_serial_device_type digi_acceleport_2_device = { | 506 | static struct usb_serial_driver digi_acceleport_2_device = { |
507 | .owner = THIS_MODULE, | 507 | .driver = { |
508 | .name = "Digi 2 port USB adapter", | 508 | .owner = THIS_MODULE, |
509 | .short_name = "digi_2", | 509 | .name = "digi_2", |
510 | }, | ||
511 | .description = "Digi 2 port USB adapter", | ||
510 | .id_table = id_table_2, | 512 | .id_table = id_table_2, |
511 | .num_interrupt_in = 0, | 513 | .num_interrupt_in = 0, |
512 | .num_bulk_in = 4, | 514 | .num_bulk_in = 4, |
@@ -530,10 +532,12 @@ static struct usb_serial_device_type digi_acceleport_2_device = { | |||
530 | .shutdown = digi_shutdown, | 532 | .shutdown = digi_shutdown, |
531 | }; | 533 | }; |
532 | 534 | ||
533 | static struct usb_serial_device_type digi_acceleport_4_device = { | 535 | static struct usb_serial_driver digi_acceleport_4_device = { |
534 | .owner = THIS_MODULE, | 536 | .driver = { |
535 | .name = "Digi 4 port USB adapter", | 537 | .owner = THIS_MODULE, |
536 | .short_name = "digi_4", | 538 | .name = "digi_4", |
539 | }, | ||
540 | .description = "Digi 4 port USB adapter", | ||
537 | .id_table = id_table_4, | 541 | .id_table = id_table_4, |
538 | .num_interrupt_in = 0, | 542 | .num_interrupt_in = 0, |
539 | .num_bulk_in = 5, | 543 | .num_bulk_in = 5, |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 8d562ab454a8..0b0546dcc7b9 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -112,9 +112,11 @@ static struct usb_driver empeg_driver = { | |||
112 | .id_table = id_table, | 112 | .id_table = id_table, |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static struct usb_serial_device_type empeg_device = { | 115 | static struct usb_serial_driver empeg_device = { |
116 | .owner = THIS_MODULE, | 116 | .driver = { |
117 | .name = "Empeg", | 117 | .owner = THIS_MODULE, |
118 | .name = "empeg", | ||
119 | }, | ||
118 | .id_table = id_table, | 120 | .id_table = id_table, |
119 | .num_interrupt_in = 0, | 121 | .num_interrupt_in = 0, |
120 | .num_bulk_in = 1, | 122 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5a8631c8a4a7..61204bf7cd78 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -411,6 +411,8 @@ static struct usb_device_id id_table_combined [] = { | |||
411 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, | 411 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, |
412 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) }, | 412 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UR100_PID) }, |
413 | { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, | 413 | { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) }, |
414 | { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) }, | ||
415 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, | ||
414 | /* | 416 | /* |
415 | * These will probably use user-space drivers. Uncomment them if | 417 | * These will probably use user-space drivers. Uncomment them if |
416 | * you need them or use the user-specified vendor/product module | 418 | * you need them or use the user-specified vendor/product module |
@@ -428,7 +430,6 @@ static struct usb_device_id id_table_combined [] = { | |||
428 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */ | 430 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_T1100_PID) }, */ |
429 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */ | 431 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCD200_PID) }, */ |
430 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */ | 432 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_ULA200_PID) }, */ |
431 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) }, */ | ||
432 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */ | 433 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_CSI8_PID) }, */ |
433 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */ | 434 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1000DL_PID) }, */ |
434 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */ | 435 | /* { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, */ |
@@ -471,6 +472,9 @@ static struct usb_device_id id_table_combined [] = { | |||
471 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | 472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, |
472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | 473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, |
473 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 474 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
475 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | ||
476 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | ||
477 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, | ||
474 | { }, /* Optional parameter entry */ | 478 | { }, /* Optional parameter entry */ |
475 | { } /* Terminating entry */ | 479 | { } /* Terminating entry */ |
476 | }; | 480 | }; |
@@ -558,10 +562,12 @@ static unsigned short int ftdi_232am_baud_to_divisor (int baud); | |||
558 | static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); | 562 | static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); |
559 | static __u32 ftdi_232bm_baud_to_divisor (int baud); | 563 | static __u32 ftdi_232bm_baud_to_divisor (int baud); |
560 | 564 | ||
561 | static struct usb_serial_device_type ftdi_sio_device = { | 565 | static struct usb_serial_driver ftdi_sio_device = { |
562 | .owner = THIS_MODULE, | 566 | .driver = { |
563 | .name = "FTDI USB Serial Device", | 567 | .owner = THIS_MODULE, |
564 | .short_name = "ftdi_sio", | 568 | .name = "ftdi_sio", |
569 | }, | ||
570 | .description = "FTDI USB Serial Device", | ||
565 | .id_table = id_table_combined, | 571 | .id_table = id_table_combined, |
566 | .num_interrupt_in = 0, | 572 | .num_interrupt_in = 0, |
567 | .num_bulk_in = 1, | 573 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 2c35d74cc6d6..ddb63df31ce6 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -199,6 +199,19 @@ | |||
199 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ | 199 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ |
200 | 200 | ||
201 | /* | 201 | /* |
202 | * Definitions for Artemis astronomical USB based cameras | ||
203 | * Check it at http://www.artemisccd.co.uk/ | ||
204 | */ | ||
205 | #define FTDI_ARTEMIS_PID 0xDF28 /* All Artemis Cameras */ | ||
206 | |||
207 | /* | ||
208 | * Definitions for ATIK Instruments astronomical USB based cameras | ||
209 | * Check it at http://www.atik-instruments.com/ | ||
210 | */ | ||
211 | #define FTDI_ATIK_ATK16_PID 0xDF30 /* ATIK ATK-16 Camera */ | ||
212 | #define FTDI_ATIK_ATK16HR_PID 0xDF31 /* ATIK ATK-16HR Camera */ | ||
213 | |||
214 | /* | ||
202 | * Protego product ids | 215 | * Protego product ids |
203 | */ | 216 | */ |
204 | #define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ | 217 | #define PROTEGO_SPECIAL_1 0xFC70 /* special/unknown device */ |
@@ -329,6 +342,9 @@ | |||
329 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | 342 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ |
330 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | 343 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ |
331 | 344 | ||
345 | /* Pyramid Computer GmbH */ | ||
346 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | ||
347 | |||
332 | /* Commands */ | 348 | /* Commands */ |
333 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 349 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
334 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 350 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 2ef614d5c8f2..35820bda7ae1 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1468,16 +1468,13 @@ static void garmin_shutdown (struct usb_serial *serial) | |||
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | 1470 | ||
1471 | |||
1472 | |||
1473 | |||
1474 | |||
1475 | |||
1476 | /* All of the device info needed */ | 1471 | /* All of the device info needed */ |
1477 | static struct usb_serial_device_type garmin_device = { | 1472 | static struct usb_serial_driver garmin_device = { |
1478 | .owner = THIS_MODULE, | 1473 | .driver = { |
1479 | .name = "Garmin GPS usb/tty", | 1474 | .owner = THIS_MODULE, |
1480 | .short_name = "garmin_gps", | 1475 | .name = "garmin_gps", |
1476 | }, | ||
1477 | .description = "Garmin GPS usb/tty", | ||
1481 | .id_table = id_table, | 1478 | .id_table = id_table, |
1482 | .num_interrupt_in = 1, | 1479 | .num_interrupt_in = 1, |
1483 | .num_bulk_in = 1, | 1480 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 5f7d3193d355..8909208f506a 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -36,10 +36,11 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); | |||
36 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | 36 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ |
37 | 37 | ||
38 | /* All of the device info needed for the Generic Serial Converter */ | 38 | /* All of the device info needed for the Generic Serial Converter */ |
39 | struct usb_serial_device_type usb_serial_generic_device = { | 39 | struct usb_serial_driver usb_serial_generic_device = { |
40 | .owner = THIS_MODULE, | 40 | .driver = { |
41 | .name = "Generic", | 41 | .owner = THIS_MODULE, |
42 | .short_name = "generic", | 42 | .name = "generic", |
43 | }, | ||
43 | .id_table = generic_device_ids, | 44 | .id_table = generic_device_ids, |
44 | .num_interrupt_in = NUM_DONT_CARE, | 45 | .num_interrupt_in = NUM_DONT_CARE, |
45 | .num_bulk_in = NUM_DONT_CARE, | 46 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 64d55fbd206e..8eadfb705601 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -38,15 +38,17 @@ MODULE_DEVICE_TABLE(usb, id_table); | |||
38 | 38 | ||
39 | static struct usb_driver hp49gp_driver = { | 39 | static struct usb_driver hp49gp_driver = { |
40 | .owner = THIS_MODULE, | 40 | .owner = THIS_MODULE, |
41 | .name = "HP4X", | 41 | .name = "hp4X", |
42 | .probe = usb_serial_probe, | 42 | .probe = usb_serial_probe, |
43 | .disconnect = usb_serial_disconnect, | 43 | .disconnect = usb_serial_disconnect, |
44 | .id_table = id_table, | 44 | .id_table = id_table, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct usb_serial_device_type hp49gp_device = { | 47 | static struct usb_serial_driver hp49gp_device = { |
48 | .owner = THIS_MODULE, | 48 | .driver = { |
49 | .name = "HP4X", | 49 | .owner = THIS_MODULE, |
50 | .name = "hp4X", | ||
51 | }, | ||
50 | .id_table = id_table, | 52 | .id_table = id_table, |
51 | .num_interrupt_in = NUM_DONT_CARE, | 53 | .num_interrupt_in = NUM_DONT_CARE, |
52 | .num_bulk_in = NUM_DONT_CARE, | 54 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 04bfe279d763..dc4c498bd1ed 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -27,225 +27,6 @@ | |||
27 | * Networks technical support, or Peter Berger <pberger@brimson.com>, | 27 | * Networks technical support, or Peter Berger <pberger@brimson.com>, |
28 | * or Al Borchers <alborchers@steinerpoint.com>. | 28 | * or Al Borchers <alborchers@steinerpoint.com>. |
29 | * | 29 | * |
30 | * Version history: | ||
31 | * | ||
32 | * 2003_04_03 al borchers | ||
33 | * - fixed a bug (that shows up with dosemu) where the tty struct is | ||
34 | * used in a callback after it has been freed | ||
35 | * | ||
36 | * 2.3 2002_03_08 greg kroah-hartman | ||
37 | * - fixed bug when multiple devices were attached at the same time. | ||
38 | * | ||
39 | * 2.2 2001_11_14 greg kroah-hartman | ||
40 | * - fixed bug in edge_close that kept the port from being used more | ||
41 | * than once. | ||
42 | * - fixed memory leak on device removal. | ||
43 | * - fixed potential double free of memory when command urb submitting | ||
44 | * failed. | ||
45 | * - other small cleanups when the device is removed | ||
46 | * | ||
47 | * 2.1 2001_07_09 greg kroah-hartman | ||
48 | * - added support for TIOCMBIS and TIOCMBIC. | ||
49 | * | ||
50 | * (04/08/2001) gb | ||
51 | * - Identify version on module load. | ||
52 | * | ||
53 | * 2.0 2001_03_05 greg kroah-hartman | ||
54 | * - reworked entire driver to fit properly in with the other usb-serial | ||
55 | * drivers. Occasional oopses still happen, but it's a good start. | ||
56 | * | ||
57 | * 1.2.3 (02/23/2001) greg kroah-hartman | ||
58 | * - changed device table to work properly for 2.4.x final format. | ||
59 | * - fixed problem with dropping data at high data rates. | ||
60 | * | ||
61 | * 1.2.2 (11/27/2000) greg kroah-hartman | ||
62 | * - cleaned up more NTisms. | ||
63 | * - Added device table for 2.4.0-test11 | ||
64 | * | ||
65 | * 1.2.1 (11/08/2000) greg kroah-hartman | ||
66 | * - Started to clean up NTisms. | ||
67 | * - Fixed problem with dev field of urb for kernels >= 2.4.0-test9 | ||
68 | * | ||
69 | * 1.2 (10/17/2000) David Iacovelli | ||
70 | * Remove all EPIC code and GPL source | ||
71 | * Fix RELEVANT_IFLAG macro to include flow control | ||
72 | * changes port configuration changes. | ||
73 | * Fix redefinition of SERIAL_MAGIC | ||
74 | * Change all timeout values to 5 seconds | ||
75 | * Tried to fix the UHCI multiple urb submission, but failed miserably. | ||
76 | * it seems to work fine with OHCI. | ||
77 | * ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must | ||
78 | * find a way to work arount this UHCI bug ) | ||
79 | * | ||
80 | * 1.1 (10/11/2000) David Iacovelli | ||
81 | * Fix XON/XOFF flow control to support both IXON and IXOFF | ||
82 | * | ||
83 | * 0.9.27 (06/30/2000) David Iacovelli | ||
84 | * Added transmit queue and now allocate urb for command writes. | ||
85 | * | ||
86 | * 0.9.26 (06/29/2000) David Iacovelli | ||
87 | * Add support for 80251 based edgeport | ||
88 | * | ||
89 | * 0.9.25 (06/27/2000) David Iacovelli | ||
90 | * Do not close the port if it has multiple opens. | ||
91 | * | ||
92 | * 0.9.24 (05/26/2000) David Iacovelli | ||
93 | * Add IOCTLs to support RXTX and JAVA POS | ||
94 | * and first cut at running BlackBox Demo | ||
95 | * | ||
96 | * 0.9.23 (05/24/2000) David Iacovelli | ||
97 | * Add IOCTLs to support RXTX and JAVA POS | ||
98 | * | ||
99 | * 0.9.22 (05/23/2000) David Iacovelli | ||
100 | * fixed bug in enumeration. If epconfig turns on mapping by | ||
101 | * path after a device is already plugged in, we now update | ||
102 | * the mapping correctly | ||
103 | * | ||
104 | * 0.9.21 (05/16/2000) David Iacovelli | ||
105 | * Added BlockUntilChaseResp() to also wait for txcredits | ||
106 | * Updated the way we allocate and handle write URBs | ||
107 | * Add debug code to dump buffers | ||
108 | * | ||
109 | * 0.9.20 (05/01/2000) David Iacovelli | ||
110 | * change driver to use usb/tts/ | ||
111 | * | ||
112 | * 0.9.19 (05/01/2000) David Iacovelli | ||
113 | * Update code to compile if DEBUG is off | ||
114 | * | ||
115 | * 0.9.18 (04/28/2000) David Iacovelli | ||
116 | * cleanup and test tty_register with devfs | ||
117 | * | ||
118 | * 0.9.17 (04/27/2000) greg kroah-hartman | ||
119 | * changed tty_register around to be like the way it | ||
120 | * was before, but now it works properly with devfs. | ||
121 | * | ||
122 | * 0.9.16 (04/26/2000) david iacovelli | ||
123 | * Fixed bug in GetProductInfo() | ||
124 | * | ||
125 | * 0.9.15 (04/25/2000) david iacovelli | ||
126 | * Updated enumeration | ||
127 | * | ||
128 | * 0.9.14 (04/24/2000) david iacovelli | ||
129 | * Removed all config/status IOCTLS and | ||
130 | * converted to using /proc/edgeport | ||
131 | * still playing with devfs | ||
132 | * | ||
133 | * 0.9.13 (04/24/2000) david iacovelli | ||
134 | * Removed configuration based on ttyUSB0 | ||
135 | * Added support for configuration using /prod/edgeport | ||
136 | * first attempt at using devfs (not working yet!) | ||
137 | * Added IOCTL to GetProductInfo() | ||
138 | * Added support for custom baud rates | ||
139 | * Add support for random port numbers | ||
140 | * | ||
141 | * 0.9.12 (04/18/2000) david iacovelli | ||
142 | * added additional configuration IOCTLs | ||
143 | * use ttyUSB0 for configuration | ||
144 | * | ||
145 | * 0.9.11 (04/17/2000) greg kroah-hartman | ||
146 | * fixed module initialization race conditions. | ||
147 | * made all urbs dynamically allocated. | ||
148 | * made driver devfs compatible. now it only registers the tty device | ||
149 | * when the device is actually plugged in. | ||
150 | * | ||
151 | * 0.9.10 (04/13/2000) greg kroah-hartman | ||
152 | * added proc interface framework. | ||
153 | * | ||
154 | * 0.9.9 (04/13/2000) david iacovelli | ||
155 | * added enumeration code and ioctls to configure the device | ||
156 | * | ||
157 | * 0.9.8 (04/12/2000) david iacovelli | ||
158 | * Change interrupt read start when device is plugged in | ||
159 | * and stop when device is removed | ||
160 | * process interrupt reads when all ports are closed | ||
161 | * (keep value of rxBytesAvail consistent with the edgeport) | ||
162 | * set the USB_BULK_QUEUE flag so that we can shove a bunch | ||
163 | * of urbs at once down the pipe | ||
164 | * | ||
165 | * 0.9.7 (04/10/2000) david iacovelli | ||
166 | * start to add enumeration code. | ||
167 | * generate serial number for epic devices | ||
168 | * add support for kdb | ||
169 | * | ||
170 | * 0.9.6 (03/30/2000) david iacovelli | ||
171 | * add IOCTL to get string, manufacture, and boot descriptors | ||
172 | * | ||
173 | * 0.9.5 (03/14/2000) greg kroah-hartman | ||
174 | * more error checking added to SerialOpen to try to fix UHCI open problem | ||
175 | * | ||
176 | * 0.9.4 (03/09/2000) greg kroah-hartman | ||
177 | * added more error checking to handle oops when data is hanging | ||
178 | * around and tty is abruptly closed. | ||
179 | * | ||
180 | * 0.9.3 (03/09/2000) david iacovelli | ||
181 | * Add epic support for xon/xoff chars | ||
182 | * play with performance | ||
183 | * | ||
184 | * 0.9.2 (03/08/2000) greg kroah-hartman | ||
185 | * changed most "info" calls to "dbg" | ||
186 | * implemented flow control properly in the termios call | ||
187 | * | ||
188 | * 0.9.1 (03/08/2000) david iacovelli | ||
189 | * added EPIC support | ||
190 | * enabled bootloader update | ||
191 | * | ||
192 | * 0.9 (03/08/2000) greg kroah-hartman | ||
193 | * Release to IO networks. | ||
194 | * Integrated changes that David made | ||
195 | * made getting urbs for writing SMP safe | ||
196 | * | ||
197 | * 0.8 (03/07/2000) greg kroah-hartman | ||
198 | * Release to IO networks. | ||
199 | * Fixed problems that were seen in code by David. | ||
200 | * Now both Edgeport/4 and Edgeport/2 works properly. | ||
201 | * Changed most of the functions to use port instead of serial. | ||
202 | * | ||
203 | * 0.7 (02/27/2000) greg kroah-hartman | ||
204 | * Milestone 3 release. | ||
205 | * Release to IO Networks | ||
206 | * ioctl for waiting on line change implemented. | ||
207 | * ioctl for getting statistics implemented. | ||
208 | * multiport support working. | ||
209 | * lsr and msr registers are now handled properly. | ||
210 | * change break now hooked up and working. | ||
211 | * support for all known Edgeport devices. | ||
212 | * | ||
213 | * 0.6 (02/22/2000) greg kroah-hartman | ||
214 | * Release to IO networks. | ||
215 | * CHASE is implemented correctly when port is closed. | ||
216 | * SerialOpen now blocks correctly until port is fully opened. | ||
217 | * | ||
218 | * 0.5 (02/20/2000) greg kroah-hartman | ||
219 | * Release to IO networks. | ||
220 | * Known problems: | ||
221 | * modem status register changes are not sent on to the user | ||
222 | * CHASE is not implemented when the port is closed. | ||
223 | * | ||
224 | * 0.4 (02/16/2000) greg kroah-hartman | ||
225 | * Second cut at the CeBit demo. | ||
226 | * Doesn't leak memory on every write to the port | ||
227 | * Still small leaks on startup. | ||
228 | * Added support for Edgeport/2 and Edgeport/8 | ||
229 | * | ||
230 | * 0.3 (02/15/2000) greg kroah-hartman | ||
231 | * CeBit demo release. | ||
232 | * Force the line settings to 4800, 8, 1, e for the demo. | ||
233 | * Warning! This version leaks memory like crazy! | ||
234 | * | ||
235 | * 0.2 (01/30/2000) greg kroah-hartman | ||
236 | * Milestone 1 release. | ||
237 | * Device is found by USB subsystem, enumerated, fimware is downloaded | ||
238 | * and the descriptors are printed to the debug log, config is set, and | ||
239 | * green light starts to blink. Open port works, and data can be sent | ||
240 | * and received at the default settings of the UART. Loopback connector | ||
241 | * and debug log confirms this. | ||
242 | * | ||
243 | * 0.1 (01/23/2000) greg kroah-hartman | ||
244 | * Initial release to help IO Networks try to set up their test system. | ||
245 | * Edgeport4 is recognized, firmware is downloaded, config is set so | ||
246 | * device blinks green light every 3 sec. Port is bound, but opening, | ||
247 | * closing, and sending data do not work properly. | ||
248 | * | ||
249 | */ | 30 | */ |
250 | 31 | ||
251 | #include <linux/config.h> | 32 | #include <linux/config.h> |
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index e7ffe02408bd..fad561c04c76 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
@@ -75,10 +75,12 @@ static struct usb_device_id id_table_combined [] = { | |||
75 | 75 | ||
76 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 76 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
77 | 77 | ||
78 | static struct usb_serial_device_type edgeport_2port_device = { | 78 | static struct usb_serial_driver edgeport_2port_device = { |
79 | .owner = THIS_MODULE, | 79 | .driver = { |
80 | .name = "Edgeport 2 port adapter", | 80 | .owner = THIS_MODULE, |
81 | .short_name = "edgeport_2", | 81 | .name = "edgeport_2", |
82 | }, | ||
83 | .description = "Edgeport 2 port adapter", | ||
82 | .id_table = edgeport_2port_id_table, | 84 | .id_table = edgeport_2port_id_table, |
83 | .num_interrupt_in = 1, | 85 | .num_interrupt_in = 1, |
84 | .num_bulk_in = 1, | 86 | .num_bulk_in = 1, |
@@ -103,10 +105,12 @@ static struct usb_serial_device_type edgeport_2port_device = { | |||
103 | .write_bulk_callback = edge_bulk_out_data_callback, | 105 | .write_bulk_callback = edge_bulk_out_data_callback, |
104 | }; | 106 | }; |
105 | 107 | ||
106 | static struct usb_serial_device_type edgeport_4port_device = { | 108 | static struct usb_serial_driver edgeport_4port_device = { |
107 | .owner = THIS_MODULE, | 109 | .driver = { |
108 | .name = "Edgeport 4 port adapter", | 110 | .owner = THIS_MODULE, |
109 | .short_name = "edgeport_4", | 111 | .name = "edgeport_4", |
112 | }, | ||
113 | .description = "Edgeport 4 port adapter", | ||
110 | .id_table = edgeport_4port_id_table, | 114 | .id_table = edgeport_4port_id_table, |
111 | .num_interrupt_in = 1, | 115 | .num_interrupt_in = 1, |
112 | .num_bulk_in = 1, | 116 | .num_bulk_in = 1, |
@@ -131,10 +135,12 @@ static struct usb_serial_device_type edgeport_4port_device = { | |||
131 | .write_bulk_callback = edge_bulk_out_data_callback, | 135 | .write_bulk_callback = edge_bulk_out_data_callback, |
132 | }; | 136 | }; |
133 | 137 | ||
134 | static struct usb_serial_device_type edgeport_8port_device = { | 138 | static struct usb_serial_driver edgeport_8port_device = { |
135 | .owner = THIS_MODULE, | 139 | .driver = { |
136 | .name = "Edgeport 8 port adapter", | 140 | .owner = THIS_MODULE, |
137 | .short_name = "edgeport_8", | 141 | .name = "edgeport_8", |
142 | }, | ||
143 | .description = "Edgeport 8 port adapter", | ||
138 | .id_table = edgeport_8port_id_table, | 144 | .id_table = edgeport_8port_id_table, |
139 | .num_interrupt_in = 1, | 145 | .num_interrupt_in = 1, |
140 | .num_bulk_in = 1, | 146 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index ebf9967f7c86..832b6d6734c0 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -2982,10 +2982,12 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf, | |||
2982 | } | 2982 | } |
2983 | 2983 | ||
2984 | 2984 | ||
2985 | static struct usb_serial_device_type edgeport_1port_device = { | 2985 | static struct usb_serial_driver edgeport_1port_device = { |
2986 | .owner = THIS_MODULE, | 2986 | .driver = { |
2987 | .name = "Edgeport TI 1 port adapter", | 2987 | .owner = THIS_MODULE, |
2988 | .short_name = "edgeport_ti_1", | 2988 | .name = "edgeport_ti_1", |
2989 | }, | ||
2990 | .description = "Edgeport TI 1 port adapter", | ||
2989 | .id_table = edgeport_1port_id_table, | 2991 | .id_table = edgeport_1port_id_table, |
2990 | .num_interrupt_in = 1, | 2992 | .num_interrupt_in = 1, |
2991 | .num_bulk_in = 1, | 2993 | .num_bulk_in = 1, |
@@ -3010,10 +3012,12 @@ static struct usb_serial_device_type edgeport_1port_device = { | |||
3010 | .write_bulk_callback = edge_bulk_out_callback, | 3012 | .write_bulk_callback = edge_bulk_out_callback, |
3011 | }; | 3013 | }; |
3012 | 3014 | ||
3013 | static struct usb_serial_device_type edgeport_2port_device = { | 3015 | static struct usb_serial_driver edgeport_2port_device = { |
3014 | .owner = THIS_MODULE, | 3016 | .driver = { |
3015 | .name = "Edgeport TI 2 port adapter", | 3017 | .owner = THIS_MODULE, |
3016 | .short_name = "edgeport_ti_2", | 3018 | .name = "edgeport_ti_2", |
3019 | }, | ||
3020 | .description = "Edgeport TI 2 port adapter", | ||
3017 | .id_table = edgeport_2port_id_table, | 3021 | .id_table = edgeport_2port_id_table, |
3018 | .num_interrupt_in = 1, | 3022 | .num_interrupt_in = 1, |
3019 | .num_bulk_in = 2, | 3023 | .num_bulk_in = 2, |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index c05c2a2a0f31..d5d066488100 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -92,24 +92,7 @@ static void ipaq_destroy_lists(struct usb_serial_port *port); | |||
92 | static struct usb_device_id ipaq_id_table [] = { | 92 | static struct usb_device_id ipaq_id_table [] = { |
93 | /* The first entry is a placeholder for the insmod-specified device */ | 93 | /* The first entry is a placeholder for the insmod-specified device */ |
94 | { USB_DEVICE(0x049F, 0x0003) }, | 94 | { USB_DEVICE(0x049F, 0x0003) }, |
95 | { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */ | 95 | { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */ |
96 | { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */ | ||
97 | { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */ | ||
98 | { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */ | ||
99 | { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */ | ||
100 | { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */ | ||
101 | { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */ | ||
102 | { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */ | ||
103 | { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */ | ||
104 | { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */ | ||
105 | { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */ | ||
106 | { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */ | ||
107 | { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */ | ||
108 | { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */ | ||
109 | { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */ | ||
110 | { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */ | ||
111 | { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */ | ||
112 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ | ||
113 | { USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */ | 96 | { USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */ |
114 | { USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */ | 97 | { USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */ |
115 | { USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */ | 98 | { USB_DEVICE(0x03F0, 0x1216) }, /* HP USB Sync 1612 */ |
@@ -125,7 +108,13 @@ static struct usb_device_id ipaq_id_table [] = { | |||
125 | { USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */ | 108 | { USB_DEVICE(0x03F0, 0x5016) }, /* HP USB Sync 1650 */ |
126 | { USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */ | 109 | { USB_DEVICE(0x03F0, 0x5116) }, /* HP USB Sync 1651 */ |
127 | { USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */ | 110 | { USB_DEVICE(0x03F0, 0x5216) }, /* HP USB Sync 1652 */ |
128 | { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */ | 111 | { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */ |
112 | { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */ | ||
113 | { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */ | ||
114 | { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */ | ||
115 | { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */ | ||
116 | { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */ | ||
117 | { USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */ | ||
129 | { USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */ | 118 | { USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */ |
130 | { USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */ | 119 | { USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */ |
131 | { USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */ | 120 | { USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */ |
@@ -251,17 +240,81 @@ static struct usb_device_id ipaq_id_table [] = { | |||
251 | { USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */ | 240 | { USB_DEVICE(0x045E, 0x04E8) }, /* Windows Powered Smartphone 2003 */ |
252 | { USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */ | 241 | { USB_DEVICE(0x045E, 0x04E9) }, /* Windows Powered Smartphone 2003 */ |
253 | { USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */ | 242 | { USB_DEVICE(0x045E, 0x04EA) }, /* Windows Powered Smartphone 2003 */ |
254 | { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */ | 243 | { USB_DEVICE(0x049F, 0x0003) }, /* Compaq iPAQ USB Sync */ |
255 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ | 244 | { USB_DEVICE(0x049F, 0x0032) }, /* Compaq iPAQ USB Sync */ |
256 | { USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */ | 245 | { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */ |
246 | { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ | ||
247 | { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ | ||
248 | { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ | ||
249 | { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ | ||
250 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ | ||
251 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ | ||
252 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | ||
253 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | ||
254 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | ||
255 | { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */ | ||
256 | { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */ | ||
257 | { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */ | ||
258 | { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */ | ||
259 | { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */ | ||
260 | { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */ | ||
261 | { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */ | ||
262 | { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */ | ||
263 | { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */ | ||
264 | { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */ | ||
265 | { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */ | ||
266 | { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */ | ||
267 | { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */ | ||
268 | { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */ | ||
269 | { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */ | ||
270 | { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */ | ||
271 | { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */ | ||
272 | { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */ | ||
273 | { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */ | ||
274 | { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */ | ||
275 | { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */ | ||
276 | { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */ | ||
277 | { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */ | ||
278 | { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */ | ||
279 | { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */ | ||
280 | { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */ | ||
281 | { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */ | ||
282 | { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */ | ||
283 | { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */ | ||
284 | { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */ | ||
285 | { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */ | ||
286 | { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */ | ||
287 | { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */ | ||
288 | { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */ | ||
289 | { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */ | ||
290 | { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */ | ||
291 | { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */ | ||
292 | { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */ | ||
293 | { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */ | ||
294 | { USB_DEVICE(0x07CF, 0x2001) }, /* CASIO USB Sync 2001 */ | ||
295 | { USB_DEVICE(0x07CF, 0x2002) }, /* CASIO USB Sync 2002 */ | ||
296 | { USB_DEVICE(0x07CF, 0x2003) }, /* CASIO USB Sync 2003 */ | ||
257 | { USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */ | 297 | { USB_DEVICE(0x0930, 0x0700) }, /* TOSHIBA USB Sync 0700 */ |
258 | { USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */ | 298 | { USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */ |
299 | { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */ | ||
259 | { USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */ | 300 | { USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */ |
260 | { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */ | 301 | { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */ |
261 | { USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */ | ||
262 | { USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */ | 302 | { USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */ |
263 | { USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */ | 303 | { USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */ |
264 | { USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */ | 304 | { USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */ |
305 | { USB_DEVICE(0x094B, 0x0001) }, /* Linkup Systems USB Sync */ | ||
306 | { USB_DEVICE(0x0960, 0x0065) }, /* BCOM USB Sync 0065 */ | ||
307 | { USB_DEVICE(0x0960, 0x0066) }, /* BCOM USB Sync 0066 */ | ||
308 | { USB_DEVICE(0x0960, 0x0067) }, /* BCOM USB Sync 0067 */ | ||
309 | { USB_DEVICE(0x0961, 0x0010) }, /* Portatec USB Sync */ | ||
310 | { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */ | ||
311 | { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */ | ||
312 | { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */ | ||
313 | { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */ | ||
314 | { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */ | ||
315 | { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */ | ||
316 | { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ | ||
317 | { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ | ||
265 | { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ | 318 | { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */ |
266 | { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ | 319 | { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */ |
267 | { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ | 320 | { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */ |
@@ -422,116 +475,67 @@ static struct usb_device_id ipaq_id_table [] = { | |||
422 | { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */ | 475 | { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */ |
423 | { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */ | 476 | { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */ |
424 | { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */ | 477 | { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */ |
425 | { USB_DEVICE(0x0409, 0x00D5) }, /* NEC USB Sync */ | ||
426 | { USB_DEVICE(0x0409, 0x00D6) }, /* NEC USB Sync */ | ||
427 | { USB_DEVICE(0x0409, 0x00D7) }, /* NEC USB Sync */ | ||
428 | { USB_DEVICE(0x0409, 0x8024) }, /* NEC USB Sync */ | ||
429 | { USB_DEVICE(0x0409, 0x8025) }, /* NEC USB Sync */ | ||
430 | { USB_DEVICE(0x04A4, 0x0014) }, /* Hitachi USB Sync */ | ||
431 | { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */ | 478 | { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */ |
432 | { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */ | 479 | { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */ |
433 | { USB_DEVICE(0x0502, 0x16E1) }, /* Acer n10 Handheld USB Sync */ | ||
434 | { USB_DEVICE(0x0502, 0x16E3) }, /* Acer n30 Handheld USB Sync */ | ||
435 | { USB_DEVICE(0x0502, 0x16E2) }, /* Acer n20 Handheld USB Sync */ | ||
436 | { USB_DEVICE(0x0502, 0x1631) }, /* c10 Series */ | ||
437 | { USB_DEVICE(0x0502, 0x1632) }, /* c20 Series */ | ||
438 | { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */ | ||
439 | { USB_DEVICE(0x0B05, 0x420F) }, /* ASUS USB Sync */ | ||
440 | { USB_DEVICE(0x0B05, 0x4200) }, /* ASUS USB Sync */ | ||
441 | { USB_DEVICE(0x0B05, 0x4201) }, /* ASUS USB Sync */ | ||
442 | { USB_DEVICE(0x0B05, 0x4202) }, /* ASUS USB Sync */ | ||
443 | { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */ | ||
444 | { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ | 480 | { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ |
445 | { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */ | 481 | { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */ |
446 | { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */ | 482 | { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */ |
447 | { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */ | 483 | { USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */ |
484 | { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */ | ||
485 | { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */ | ||
486 | { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */ | ||
487 | { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */ | ||
488 | { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */ | ||
448 | { USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */ | 489 | { USB_DEVICE(0x1066, 0x0300) }, /* E-TEN P3XX Pocket PC */ |
449 | { USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */ | 490 | { USB_DEVICE(0x1066, 0x0500) }, /* E-TEN P5XX Pocket PC */ |
450 | { USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */ | 491 | { USB_DEVICE(0x1066, 0x0600) }, /* E-TEN P6XX Pocket PC */ |
451 | { USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */ | 492 | { USB_DEVICE(0x1066, 0x0700) }, /* E-TEN P7XX Pocket PC */ |
452 | { USB_DEVICE(0x1066, 0x00CE) }, /* E-TEN USB Sync */ | 493 | { USB_DEVICE(0x1114, 0x0001) }, /* Psion Teklogix Sync 753x */ |
453 | { USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */ | 494 | { USB_DEVICE(0x1114, 0x0004) }, /* Psion Teklogix Sync netBookPro */ |
454 | { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ | 495 | { USB_DEVICE(0x1114, 0x0006) }, /* Psion Teklogix Sync 7525 */ |
455 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ | 496 | { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */ |
456 | { USB_DEVICE(0x067E, 0x1001) }, /* Intermec Mobile Computer */ | 497 | { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */ |
457 | { USB_DEVICE(0x04f1, 0x3011) }, /* JVC USB Sync */ | 498 | { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */ |
458 | { USB_DEVICE(0x04F1, 0x3012) }, /* JVC USB Sync */ | 499 | { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */ |
459 | { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */ | 500 | { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */ |
460 | { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */ | 501 | { USB_DEVICE(0x1690, 0x0601) }, /* Askey USB Sync */ |
461 | { USB_DEVICE(0x043E, 0x9C01) }, /* LGE USB Sync */ | 502 | { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */ |
462 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ | 503 | { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */ |
463 | { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */ | 504 | { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */ |
464 | { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */ | 505 | { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */ |
465 | { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */ | 506 | { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */ |
466 | { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */ | 507 | { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */ |
467 | { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */ | ||
468 | { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */ | ||
469 | { USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */ | 508 | { USB_DEVICE(0x3340, 0x0326) }, /* Mio DigiWalker 338 */ |
470 | { USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */ | 509 | { USB_DEVICE(0x3340, 0x0426) }, /* Mio DigiWalker 338 */ |
471 | { USB_DEVICE(0x3340, 0x011C) }, /* Mio DigiWalker PPC StrongARM */ | ||
472 | { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */ | ||
473 | { USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */ | 510 | { USB_DEVICE(0x3340, 0x043A) }, /* Mio DigiWalker USB Sync */ |
474 | { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */ | ||
475 | { USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */ | 511 | { USB_DEVICE(0x3340, 0x051C) }, /* MiTAC USB Sync 528 */ |
476 | { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */ | 512 | { USB_DEVICE(0x3340, 0x053A) }, /* Mio DigiWalker SmartPhone USB Sync */ |
513 | { USB_DEVICE(0x3340, 0x071C) }, /* MiTAC USB Sync */ | ||
514 | { USB_DEVICE(0x3340, 0x0B1C) }, /* Generic PPC StrongARM */ | ||
515 | { USB_DEVICE(0x3340, 0x0E3A) }, /* Generic PPC USB Sync */ | ||
516 | { USB_DEVICE(0x3340, 0x0F1C) }, /* Itautec USB Sync */ | ||
517 | { USB_DEVICE(0x3340, 0x0F3A) }, /* Generic SmartPhone USB Sync */ | ||
518 | { USB_DEVICE(0x3340, 0x1326) }, /* Itautec USB Sync */ | ||
477 | { USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */ | 519 | { USB_DEVICE(0x3340, 0x191C) }, /* YAKUMO USB Sync */ |
520 | { USB_DEVICE(0x3340, 0x2326) }, /* Vobis USB Sync */ | ||
521 | { USB_DEVICE(0x3340, 0x3326) }, /* MEDION Winodws Moble USB Sync */ | ||
522 | { USB_DEVICE(0x3708, 0x20CE) }, /* Legend USB Sync */ | ||
523 | { USB_DEVICE(0x3708, 0x21CE) }, /* Lenovo USB Sync */ | ||
478 | { USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */ | 524 | { USB_DEVICE(0x4113, 0x0210) }, /* Mobile Media Technology USB Sync */ |
479 | { USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */ | 525 | { USB_DEVICE(0x4113, 0x0211) }, /* Mobile Media Technology USB Sync */ |
480 | { USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */ | 526 | { USB_DEVICE(0x4113, 0x0400) }, /* Mobile Media Technology USB Sync */ |
481 | { USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */ | 527 | { USB_DEVICE(0x4113, 0x0410) }, /* Mobile Media Technology USB Sync */ |
482 | { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */ | 528 | { USB_DEVICE(0x413C, 0x4001) }, /* Dell Axim USB Sync */ |
483 | { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */ | 529 | { USB_DEVICE(0x413C, 0x4002) }, /* Dell Axim USB Sync */ |
484 | { USB_DEVICE(0x04E8, 0x6611) }, /* Samsung MITs USB Sync */ | 530 | { USB_DEVICE(0x413C, 0x4003) }, /* Dell Axim USB Sync */ |
485 | { USB_DEVICE(0x04E8, 0x6613) }, /* Samsung MITs USB Sync */ | 531 | { USB_DEVICE(0x413C, 0x4004) }, /* Dell Axim USB Sync */ |
486 | { USB_DEVICE(0x04E8, 0x6615) }, /* Samsung MITs USB Sync */ | 532 | { USB_DEVICE(0x413C, 0x4005) }, /* Dell Axim USB Sync */ |
487 | { USB_DEVICE(0x04E8, 0x6617) }, /* Samsung MITs USB Sync */ | 533 | { USB_DEVICE(0x413C, 0x4006) }, /* Dell Axim USB Sync */ |
488 | { USB_DEVICE(0x04E8, 0x6619) }, /* Samsung MITs USB Sync */ | 534 | { USB_DEVICE(0x413C, 0x4007) }, /* Dell Axim USB Sync */ |
489 | { USB_DEVICE(0x04E8, 0x661B) }, /* Samsung MITs USB Sync */ | 535 | { USB_DEVICE(0x413C, 0x4008) }, /* Dell Axim USB Sync */ |
490 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | 536 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ |
491 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | ||
492 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | ||
493 | { USB_DEVICE(0x04E8, 0x5F03) }, /* Samsung NEXiO USB Sync */ | ||
494 | { USB_DEVICE(0x04E8, 0x5F04) }, /* Samsung NEXiO USB Sync */ | ||
495 | { USB_DEVICE(0x04E8, 0x662E) }, /* Samsung MITs USB Sync */ | ||
496 | { USB_DEVICE(0x04E8, 0x6630) }, /* Samsung MITs USB Sync */ | ||
497 | { USB_DEVICE(0x04E8, 0x6632) }, /* Samsung MITs USB Sync */ | ||
498 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ | 537 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ |
499 | { USB_DEVICE(0x05E0, 0x2000) }, /* Symbol USB Sync */ | 538 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ |
500 | { USB_DEVICE(0x05E0, 0x2001) }, /* Symbol USB Sync 0x2001 */ | ||
501 | { USB_DEVICE(0x05E0, 0x2002) }, /* Symbol USB Sync 0x2002 */ | ||
502 | { USB_DEVICE(0x05E0, 0x2003) }, /* Symbol USB Sync 0x2003 */ | ||
503 | { USB_DEVICE(0x05E0, 0x2004) }, /* Symbol USB Sync 0x2004 */ | ||
504 | { USB_DEVICE(0x05E0, 0x2005) }, /* Symbol USB Sync 0x2005 */ | ||
505 | { USB_DEVICE(0x05E0, 0x2006) }, /* Symbol USB Sync 0x2006 */ | ||
506 | { USB_DEVICE(0x05E0, 0x2007) }, /* Symbol USB Sync 0x2007 */ | ||
507 | { USB_DEVICE(0x05E0, 0x2008) }, /* Symbol USB Sync 0x2008 */ | ||
508 | { USB_DEVICE(0x05E0, 0x2009) }, /* Symbol USB Sync 0x2009 */ | ||
509 | { USB_DEVICE(0x05E0, 0x200A) }, /* Symbol USB Sync 0x200A */ | ||
510 | { USB_DEVICE(0x1182, 0x1388) }, /* VES USB Sync */ | ||
511 | { USB_DEVICE(0x0543, 0x0ED9) }, /* ViewSonic Color Pocket PC V35 */ | ||
512 | { USB_DEVICE(0x0543, 0x1527) }, /* ViewSonic Color Pocket PC V36 */ | ||
513 | { USB_DEVICE(0x0543, 0x1529) }, /* ViewSonic Color Pocket PC V37 */ | ||
514 | { USB_DEVICE(0x0543, 0x152B) }, /* ViewSonic Color Pocket PC V38 */ | ||
515 | { USB_DEVICE(0x0543, 0x152E) }, /* ViewSonic Pocket PC */ | ||
516 | { USB_DEVICE(0x0543, 0x1921) }, /* ViewSonic Communicator Pocket PC */ | ||
517 | { USB_DEVICE(0x0543, 0x1922) }, /* ViewSonic Smartphone */ | ||
518 | { USB_DEVICE(0x0543, 0x1923) }, /* ViewSonic Pocket PC V30 */ | ||
519 | { USB_DEVICE(0x0536, 0x01A0) }, /* HHP PDT */ | ||
520 | { USB_DEVICE(0x099E, 0x0052) }, /* Trimble GeoExplorer */ | ||
521 | { USB_DEVICE(0x099E, 0x4000) }, /* TDS Data Collector */ | ||
522 | { USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */ | ||
523 | { USB_DEVICE(0x0FB8, 0x3002) }, /* Wistron USB Sync */ | ||
524 | { USB_DEVICE(0x0FB8, 0x3003) }, /* Wistron USB Sync */ | ||
525 | { USB_DEVICE(0x0FB8, 0x4001) }, /* Wistron USB Sync */ | ||
526 | { USB_DEVICE(0x11D9, 0x1003) }, /* Rugged Pocket PC 2003 */ | ||
527 | { USB_DEVICE(0x11D9, 0x1002) }, /* Rugged Pocket PC 2003 */ | ||
528 | { USB_DEVICE(0x22B8, 0x4204) }, /* Motorola MPx200 Smartphone */ | ||
529 | { USB_DEVICE(0x22B8, 0x4214) }, /* Motorola MPc GSM */ | ||
530 | { USB_DEVICE(0x22B8, 0x4224) }, /* Motorola MPx220 Smartphone */ | ||
531 | { USB_DEVICE(0x22B8, 0x4234) }, /* Motorola MPc CDMA */ | ||
532 | { USB_DEVICE(0x22B8, 0x4244) }, /* Motorola MPx100 Smartphone */ | ||
533 | { USB_DEVICE(0x1231, 0xCE01) }, /* USB Sync 03 */ | ||
534 | { USB_DEVICE(0x1231, 0xCE02) }, /* USB Sync 03 */ | ||
535 | { } /* Terminating entry */ | 539 | { } /* Terminating entry */ |
536 | }; | 540 | }; |
537 | 541 | ||
@@ -547,9 +551,12 @@ static struct usb_driver ipaq_driver = { | |||
547 | 551 | ||
548 | 552 | ||
549 | /* All of the device info needed for the Compaq iPAQ */ | 553 | /* All of the device info needed for the Compaq iPAQ */ |
550 | static struct usb_serial_device_type ipaq_device = { | 554 | static struct usb_serial_driver ipaq_device = { |
551 | .owner = THIS_MODULE, | 555 | .driver = { |
552 | .name = "PocketPC PDA", | 556 | .owner = THIS_MODULE, |
557 | .name = "ipaq", | ||
558 | }, | ||
559 | .description = "PocketPC PDA", | ||
553 | .id_table = ipaq_id_table, | 560 | .id_table = ipaq_id_table, |
554 | .num_interrupt_in = NUM_DONT_CARE, | 561 | .num_interrupt_in = NUM_DONT_CARE, |
555 | .num_bulk_in = 1, | 562 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 85e242459c27..a02fada85362 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -443,10 +443,12 @@ static int ipw_disconnect(struct usb_serial_port *port) | |||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | 445 | ||
446 | static struct usb_serial_device_type ipw_device = { | 446 | static struct usb_serial_driver ipw_device = { |
447 | .owner = THIS_MODULE, | 447 | .driver = { |
448 | .name = "IPWireless converter", | 448 | .owner = THIS_MODULE, |
449 | .short_name = "ipw", | 449 | .name = "ipw", |
450 | }, | ||
451 | .description = "IPWireless converter", | ||
450 | .id_table = usb_ipw_ids, | 452 | .id_table = usb_ipw_ids, |
451 | .num_interrupt_in = NUM_DONT_CARE, | 453 | .num_interrupt_in = NUM_DONT_CARE, |
452 | .num_bulk_in = 1, | 454 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 937b2fdd7171..19f329e9bdcf 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -133,9 +133,12 @@ static struct usb_driver ir_driver = { | |||
133 | }; | 133 | }; |
134 | 134 | ||
135 | 135 | ||
136 | static struct usb_serial_device_type ir_device = { | 136 | static struct usb_serial_driver ir_device = { |
137 | .owner = THIS_MODULE, | 137 | .driver = { |
138 | .name = "IR Dongle", | 138 | .owner = THIS_MODULE, |
139 | .name = "ir-usb", | ||
140 | }, | ||
141 | .description = "IR Dongle", | ||
139 | .id_table = id_table, | 142 | .id_table = id_table, |
140 | .num_interrupt_in = 1, | 143 | .num_interrupt_in = 1, |
141 | .num_bulk_in = 1, | 144 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index e9b45b768aca..5cfc13b5e56f 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -570,10 +570,12 @@ static struct usb_device_id keyspan_4port_ids[] = { | |||
570 | }; | 570 | }; |
571 | 571 | ||
572 | /* Structs for the devices, pre and post renumeration. */ | 572 | /* Structs for the devices, pre and post renumeration. */ |
573 | static struct usb_serial_device_type keyspan_pre_device = { | 573 | static struct usb_serial_driver keyspan_pre_device = { |
574 | .owner = THIS_MODULE, | 574 | .driver = { |
575 | .name = "Keyspan - (without firmware)", | 575 | .owner = THIS_MODULE, |
576 | .short_name = "keyspan_no_firm", | 576 | .name = "keyspan_no_firm", |
577 | }, | ||
578 | .description = "Keyspan - (without firmware)", | ||
577 | .id_table = keyspan_pre_ids, | 579 | .id_table = keyspan_pre_ids, |
578 | .num_interrupt_in = NUM_DONT_CARE, | 580 | .num_interrupt_in = NUM_DONT_CARE, |
579 | .num_bulk_in = NUM_DONT_CARE, | 581 | .num_bulk_in = NUM_DONT_CARE, |
@@ -582,10 +584,12 @@ static struct usb_serial_device_type keyspan_pre_device = { | |||
582 | .attach = keyspan_fake_startup, | 584 | .attach = keyspan_fake_startup, |
583 | }; | 585 | }; |
584 | 586 | ||
585 | static struct usb_serial_device_type keyspan_1port_device = { | 587 | static struct usb_serial_driver keyspan_1port_device = { |
586 | .owner = THIS_MODULE, | 588 | .driver = { |
587 | .name = "Keyspan 1 port adapter", | 589 | .owner = THIS_MODULE, |
588 | .short_name = "keyspan_1", | 590 | .name = "keyspan_1", |
591 | }, | ||
592 | .description = "Keyspan 1 port adapter", | ||
589 | .id_table = keyspan_1port_ids, | 593 | .id_table = keyspan_1port_ids, |
590 | .num_interrupt_in = NUM_DONT_CARE, | 594 | .num_interrupt_in = NUM_DONT_CARE, |
591 | .num_bulk_in = NUM_DONT_CARE, | 595 | .num_bulk_in = NUM_DONT_CARE, |
@@ -607,10 +611,12 @@ static struct usb_serial_device_type keyspan_1port_device = { | |||
607 | .shutdown = keyspan_shutdown, | 611 | .shutdown = keyspan_shutdown, |
608 | }; | 612 | }; |
609 | 613 | ||
610 | static struct usb_serial_device_type keyspan_2port_device = { | 614 | static struct usb_serial_driver keyspan_2port_device = { |
611 | .owner = THIS_MODULE, | 615 | .driver = { |
612 | .name = "Keyspan 2 port adapter", | 616 | .owner = THIS_MODULE, |
613 | .short_name = "keyspan_2", | 617 | .name = "keyspan_2", |
618 | }, | ||
619 | .description = "Keyspan 2 port adapter", | ||
614 | .id_table = keyspan_2port_ids, | 620 | .id_table = keyspan_2port_ids, |
615 | .num_interrupt_in = NUM_DONT_CARE, | 621 | .num_interrupt_in = NUM_DONT_CARE, |
616 | .num_bulk_in = NUM_DONT_CARE, | 622 | .num_bulk_in = NUM_DONT_CARE, |
@@ -632,10 +638,12 @@ static struct usb_serial_device_type keyspan_2port_device = { | |||
632 | .shutdown = keyspan_shutdown, | 638 | .shutdown = keyspan_shutdown, |
633 | }; | 639 | }; |
634 | 640 | ||
635 | static struct usb_serial_device_type keyspan_4port_device = { | 641 | static struct usb_serial_driver keyspan_4port_device = { |
636 | .owner = THIS_MODULE, | 642 | .driver = { |
637 | .name = "Keyspan 4 port adapter", | 643 | .owner = THIS_MODULE, |
638 | .short_name = "keyspan_4", | 644 | .name = "keyspan_4", |
645 | }, | ||
646 | .description = "Keyspan 4 port adapter", | ||
639 | .id_table = keyspan_4port_ids, | 647 | .id_table = keyspan_4port_ids, |
640 | .num_interrupt_in = NUM_DONT_CARE, | 648 | .num_interrupt_in = NUM_DONT_CARE, |
641 | .num_bulk_in = 5, | 649 | .num_bulk_in = 5, |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 635c384cb15a..cd4f48bd83b6 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -783,10 +783,12 @@ static void keyspan_pda_shutdown (struct usb_serial *serial) | |||
783 | } | 783 | } |
784 | 784 | ||
785 | #ifdef KEYSPAN | 785 | #ifdef KEYSPAN |
786 | static struct usb_serial_device_type keyspan_pda_fake_device = { | 786 | static struct usb_serial_driver keyspan_pda_fake_device = { |
787 | .owner = THIS_MODULE, | 787 | .driver = { |
788 | .name = "Keyspan PDA - (prerenumeration)", | 788 | .owner = THIS_MODULE, |
789 | .short_name = "keyspan_pda_pre", | 789 | .name = "keyspan_pda_pre", |
790 | }, | ||
791 | .description = "Keyspan PDA - (prerenumeration)", | ||
790 | .id_table = id_table_fake, | 792 | .id_table = id_table_fake, |
791 | .num_interrupt_in = NUM_DONT_CARE, | 793 | .num_interrupt_in = NUM_DONT_CARE, |
792 | .num_bulk_in = NUM_DONT_CARE, | 794 | .num_bulk_in = NUM_DONT_CARE, |
@@ -797,10 +799,12 @@ static struct usb_serial_device_type keyspan_pda_fake_device = { | |||
797 | #endif | 799 | #endif |
798 | 800 | ||
799 | #ifdef XIRCOM | 801 | #ifdef XIRCOM |
800 | static struct usb_serial_device_type xircom_pgs_fake_device = { | 802 | static struct usb_serial_driver xircom_pgs_fake_device = { |
801 | .owner = THIS_MODULE, | 803 | .driver = { |
802 | .name = "Xircom / Entregra PGS - (prerenumeration)", | 804 | .owner = THIS_MODULE, |
803 | .short_name = "xircom_no_firm", | 805 | .name = "xircom_no_firm", |
806 | }, | ||
807 | .description = "Xircom / Entregra PGS - (prerenumeration)", | ||
804 | .id_table = id_table_fake_xircom, | 808 | .id_table = id_table_fake_xircom, |
805 | .num_interrupt_in = NUM_DONT_CARE, | 809 | .num_interrupt_in = NUM_DONT_CARE, |
806 | .num_bulk_in = NUM_DONT_CARE, | 810 | .num_bulk_in = NUM_DONT_CARE, |
@@ -810,10 +814,12 @@ static struct usb_serial_device_type xircom_pgs_fake_device = { | |||
810 | }; | 814 | }; |
811 | #endif | 815 | #endif |
812 | 816 | ||
813 | static struct usb_serial_device_type keyspan_pda_device = { | 817 | static struct usb_serial_driver keyspan_pda_device = { |
814 | .owner = THIS_MODULE, | 818 | .driver = { |
815 | .name = "Keyspan PDA", | 819 | .owner = THIS_MODULE, |
816 | .short_name = "keyspan_pda", | 820 | .name = "keyspan_pda", |
821 | }, | ||
822 | .description = "Keyspan PDA", | ||
817 | .id_table = id_table_std, | 823 | .id_table = id_table_std, |
818 | .num_interrupt_in = 1, | 824 | .num_interrupt_in = 1, |
819 | .num_bulk_in = 0, | 825 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a11e829e38c8..a8951c0fd020 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -123,10 +123,12 @@ static struct usb_driver kl5kusb105d_driver = { | |||
123 | .id_table = id_table, | 123 | .id_table = id_table, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | static struct usb_serial_device_type kl5kusb105d_device = { | 126 | static struct usb_serial_driver kl5kusb105d_device = { |
127 | .owner = THIS_MODULE, | 127 | .driver = { |
128 | .name = "KL5KUSB105D / PalmConnect", | 128 | .owner = THIS_MODULE, |
129 | .short_name = "kl5kusb105d", | 129 | .name = "kl5kusb105d", |
130 | }, | ||
131 | .description = "KL5KUSB105D / PalmConnect", | ||
130 | .id_table = id_table, | 132 | .id_table = id_table, |
131 | .num_interrupt_in = 1, | 133 | .num_interrupt_in = 1, |
132 | .num_bulk_in = 1, | 134 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index fe4c98a75171..9456dd9dd136 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -105,9 +105,12 @@ static struct usb_driver kobil_driver = { | |||
105 | }; | 105 | }; |
106 | 106 | ||
107 | 107 | ||
108 | static struct usb_serial_device_type kobil_device = { | 108 | static struct usb_serial_driver kobil_device = { |
109 | .owner = THIS_MODULE, | 109 | .driver = { |
110 | .name = "KOBIL USB smart card terminal", | 110 | .owner = THIS_MODULE, |
111 | .name = "kobil", | ||
112 | }, | ||
113 | .description = "KOBIL USB smart card terminal", | ||
111 | .id_table = id_table, | 114 | .id_table = id_table, |
112 | .num_interrupt_in = NUM_DONT_CARE, | 115 | .num_interrupt_in = NUM_DONT_CARE, |
113 | .num_bulk_in = 0, | 116 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 50b6369647d2..ca5dbadb9b7e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -132,10 +132,12 @@ static struct usb_driver mct_u232_driver = { | |||
132 | .id_table = id_table_combined, | 132 | .id_table = id_table_combined, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct usb_serial_device_type mct_u232_device = { | 135 | static struct usb_serial_driver mct_u232_device = { |
136 | .owner = THIS_MODULE, | 136 | .driver = { |
137 | .name = "MCT U232", | 137 | .owner = THIS_MODULE, |
138 | .short_name = "mct_u232", | 138 | .name = "mct_u232", |
139 | }, | ||
140 | .description = "MCT U232", | ||
139 | .id_table = id_table_combined, | 141 | .id_table = id_table_combined, |
140 | .num_interrupt_in = 2, | 142 | .num_interrupt_in = 2, |
141 | .num_bulk_in = 0, | 143 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/nokia_dku2.c b/drivers/usb/serial/nokia_dku2.c new file mode 100644 index 000000000000..fad01bef3a64 --- /dev/null +++ b/drivers/usb/serial/nokia_dku2.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Nokia DKU2 USB driver | ||
3 | * | ||
4 | * Copyright (C) 2004 | ||
5 | * Author: C Kemp | ||
6 | * | ||
7 | * This program is largely derived from work by the linux-usb group | ||
8 | * and associated source files. Please see the usb/serial files for | ||
9 | * individual credits and copyrights. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de> | ||
17 | * Added short name to device structure to make driver load into kernel 2.6.13 | ||
18 | * | ||
19 | * 20.09.2005 - Matthias Blaesing <matthias.blaesing@rwth-aachen.de> | ||
20 | * Added usb_deregister to exit code - to allow remove and reinsert of module | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/tty.h> | ||
30 | #include <linux/tty_driver.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include "usb-serial.h" | ||
35 | |||
36 | |||
37 | #define NOKIA_VENDOR_ID 0x0421 | ||
38 | #define NOKIA7600_PRODUCT_ID 0x0400 | ||
39 | #define NOKIA6230_PRODUCT_ID 0x040f | ||
40 | #define NOKIA6170_PRODUCT_ID 0x0416 | ||
41 | #define NOKIA6670_PRODUCT_ID 0x041d | ||
42 | #define NOKIA6680_PRODUCT_ID 0x041e | ||
43 | #define NOKIA6230i_PRODUCT_ID 0x0428 | ||
44 | |||
45 | #define NOKIA_AT_PORT 0x82 | ||
46 | #define NOKIA_FBUS_PORT 0x86 | ||
47 | |||
48 | /* | ||
49 | * Version Information | ||
50 | */ | ||
51 | #define DRIVER_VERSION "v0.2" | ||
52 | #define DRIVER_AUTHOR "C Kemp" | ||
53 | #define DRIVER_DESC "Nokia DKU2 Driver" | ||
54 | |||
55 | static struct usb_device_id id_table [] = { | ||
56 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA7600_PRODUCT_ID) }, | ||
57 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230_PRODUCT_ID) }, | ||
58 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6170_PRODUCT_ID) }, | ||
59 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6670_PRODUCT_ID) }, | ||
60 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6680_PRODUCT_ID) }, | ||
61 | { USB_DEVICE(NOKIA_VENDOR_ID, NOKIA6230i_PRODUCT_ID) }, | ||
62 | { } /* Terminating entry */ | ||
63 | }; | ||
64 | MODULE_DEVICE_TABLE(usb, id_table); | ||
65 | |||
66 | /* The only thing which makes this device different from a generic | ||
67 | * device is that we have to set an alternative configuration to make | ||
68 | * the relevant endpoints available. In 2.6 this is really easy... */ | ||
69 | static int nokia_probe(struct usb_serial *serial, | ||
70 | const struct usb_device_id *id) | ||
71 | { | ||
72 | int retval = -ENODEV; | ||
73 | |||
74 | if (serial->interface->altsetting[0].endpoint[0].desc.bEndpointAddress == NOKIA_AT_PORT) { | ||
75 | /* the AT port */ | ||
76 | dev_info(&serial->dev->dev, "Nokia AT Port:\n"); | ||
77 | retval = 0; | ||
78 | } else if (serial->interface->num_altsetting == 2 && | ||
79 | serial->interface->altsetting[1].endpoint[0].desc.bEndpointAddress == NOKIA_FBUS_PORT) { | ||
80 | /* the FBUS port */ | ||
81 | dev_info(&serial->dev->dev, "Nokia FBUS Port:\n"); | ||
82 | usb_set_interface(serial->dev, 10, 1); | ||
83 | retval = 0; | ||
84 | } | ||
85 | |||
86 | return retval; | ||
87 | } | ||
88 | |||
89 | static struct usb_driver nokia_driver = { | ||
90 | .owner = THIS_MODULE, | ||
91 | .name = "nokia_dku2", | ||
92 | .probe = usb_serial_probe, | ||
93 | .disconnect = usb_serial_disconnect, | ||
94 | .id_table = id_table, | ||
95 | }; | ||
96 | |||
97 | static struct usb_serial_driver nokia_serial_driver = { | ||
98 | .driver = { | ||
99 | .owner = THIS_MODULE, | ||
100 | .name = "nokia_dku2", | ||
101 | }, | ||
102 | .description = "Nokia 7600/6230(i)/6170/66x0 DKU2 driver", | ||
103 | .id_table = id_table, | ||
104 | .num_interrupt_in = 1, | ||
105 | .num_bulk_in = 1, | ||
106 | .num_bulk_out = 1, | ||
107 | .num_ports = 1, | ||
108 | .probe = nokia_probe, | ||
109 | }; | ||
110 | |||
111 | static int __init nokia_init(void) | ||
112 | { | ||
113 | int retval; | ||
114 | |||
115 | retval = usb_serial_register(&nokia_serial_driver); | ||
116 | if (retval) | ||
117 | return retval; | ||
118 | |||
119 | retval = usb_register(&nokia_driver); | ||
120 | if (retval) { | ||
121 | usb_serial_deregister(&nokia_serial_driver); | ||
122 | return retval; | ||
123 | } | ||
124 | |||
125 | info(DRIVER_VERSION " " DRIVER_AUTHOR); | ||
126 | info(DRIVER_DESC); | ||
127 | |||
128 | return retval; | ||
129 | } | ||
130 | |||
131 | static void __exit nokia_exit(void) | ||
132 | { | ||
133 | usb_deregister(&nokia_driver); | ||
134 | usb_serial_deregister(&nokia_serial_driver); | ||
135 | } | ||
136 | |||
137 | module_init(nokia_init); | ||
138 | module_exit(nokia_exit); | ||
139 | |||
140 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
141 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
142 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 6a99ae192df1..3caf97072ac0 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -88,10 +88,12 @@ static struct usb_driver omninet_driver = { | |||
88 | }; | 88 | }; |
89 | 89 | ||
90 | 90 | ||
91 | static struct usb_serial_device_type zyxel_omninet_device = { | 91 | static struct usb_serial_driver zyxel_omninet_device = { |
92 | .owner = THIS_MODULE, | 92 | .driver = { |
93 | .name = "ZyXEL - omni.net lcd plus usb", | 93 | .owner = THIS_MODULE, |
94 | .short_name = "omninet", | 94 | .name = "omninet", |
95 | }, | ||
96 | .description = "ZyXEL - omni.net lcd plus usb", | ||
95 | .id_table = id_table, | 97 | .id_table = id_table, |
96 | .num_interrupt_in = 1, | 98 | .num_interrupt_in = 1, |
97 | .num_bulk_in = 1, | 99 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 4989e5740d18..7716000045b7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -105,10 +105,12 @@ static struct usb_driver option_driver = { | |||
105 | /* The card has three separate interfaces, wich the serial driver | 105 | /* The card has three separate interfaces, wich the serial driver |
106 | * recognizes separately, thus num_port=1. | 106 | * recognizes separately, thus num_port=1. |
107 | */ | 107 | */ |
108 | static struct usb_serial_device_type option_3port_device = { | 108 | static struct usb_serial_driver option_3port_device = { |
109 | .owner = THIS_MODULE, | 109 | .driver = { |
110 | .name = "Option 3G data card", | 110 | .owner = THIS_MODULE, |
111 | .short_name = "option", | 111 | .name = "option", |
112 | }, | ||
113 | .description = "Option 3G data card", | ||
112 | .id_table = option_ids, | 114 | .id_table = option_ids, |
113 | .num_interrupt_in = NUM_DONT_CARE, | 115 | .num_interrupt_in = NUM_DONT_CARE, |
114 | .num_bulk_in = NUM_DONT_CARE, | 116 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 3cf245bdda54..165c119bf10e 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -8,31 +8,10 @@ | |||
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
11 | * the Free Software Foundation; either version 2 of the License, or | 11 | * the Free Software Foundation; either version 2 of the License. |
12 | * (at your option) any later version. | ||
13 | * | 12 | * |
14 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 13 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
15 | * | 14 | * |
16 | * 2002_Mar_26 gkh | ||
17 | * allowed driver to work properly if there is no tty assigned to a port | ||
18 | * (this happens for serial console devices.) | ||
19 | * | ||
20 | * 2001_Oct_06 gkh | ||
21 | * Added RTS and DTR line control. Thanks to joe@bndlg.de for parts of it. | ||
22 | * | ||
23 | * 2001_Sep_19 gkh | ||
24 | * Added break support. | ||
25 | * | ||
26 | * 2001_Aug_30 gkh | ||
27 | * fixed oops in write_bulk_callback. | ||
28 | * | ||
29 | * 2001_Aug_28 gkh | ||
30 | * reworked buffer logic to be like other usb-serial drivers. Hopefully | ||
31 | * removing some reported problems. | ||
32 | * | ||
33 | * 2001_Jun_06 gkh | ||
34 | * finished porting to 2.4 format. | ||
35 | * | ||
36 | */ | 15 | */ |
37 | 16 | ||
38 | #include <linux/config.h> | 17 | #include <linux/config.h> |
@@ -55,7 +34,6 @@ | |||
55 | /* | 34 | /* |
56 | * Version Information | 35 | * Version Information |
57 | */ | 36 | */ |
58 | #define DRIVER_VERSION "v0.12" | ||
59 | #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" | 37 | #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver" |
60 | 38 | ||
61 | static int debug; | 39 | static int debug; |
@@ -175,9 +153,11 @@ static unsigned int pl2303_buf_get(struct pl2303_buf *pb, char *buf, | |||
175 | 153 | ||
176 | 154 | ||
177 | /* All of the device info needed for the PL2303 SIO serial converter */ | 155 | /* All of the device info needed for the PL2303 SIO serial converter */ |
178 | static struct usb_serial_device_type pl2303_device = { | 156 | static struct usb_serial_driver pl2303_device = { |
179 | .owner = THIS_MODULE, | 157 | .driver = { |
180 | .name = "PL-2303", | 158 | .owner = THIS_MODULE, |
159 | .name = "pl2303", | ||
160 | }, | ||
181 | .id_table = id_table, | 161 | .id_table = id_table, |
182 | .num_interrupt_in = NUM_DONT_CARE, | 162 | .num_interrupt_in = NUM_DONT_CARE, |
183 | .num_bulk_in = 1, | 163 | .num_bulk_in = 1, |
@@ -1195,7 +1175,7 @@ static int __init pl2303_init (void) | |||
1195 | retval = usb_register(&pl2303_driver); | 1175 | retval = usb_register(&pl2303_driver); |
1196 | if (retval) | 1176 | if (retval) |
1197 | goto failed_usb_register; | 1177 | goto failed_usb_register; |
1198 | info(DRIVER_DESC " " DRIVER_VERSION); | 1178 | info(DRIVER_DESC); |
1199 | return 0; | 1179 | return 0; |
1200 | failed_usb_register: | 1180 | failed_usb_register: |
1201 | usb_serial_deregister(&pl2303_device); | 1181 | usb_serial_deregister(&pl2303_device); |
@@ -1215,7 +1195,6 @@ module_init(pl2303_init); | |||
1215 | module_exit(pl2303_exit); | 1195 | module_exit(pl2303_exit); |
1216 | 1196 | ||
1217 | MODULE_DESCRIPTION(DRIVER_DESC); | 1197 | MODULE_DESCRIPTION(DRIVER_DESC); |
1218 | MODULE_VERSION(DRIVER_VERSION); | ||
1219 | MODULE_LICENSE("GPL"); | 1198 | MODULE_LICENSE("GPL"); |
1220 | 1199 | ||
1221 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 1200 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 96a17568cbf1..c22bdc0c4dfd 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -92,7 +92,7 @@ MODULE_DESCRIPTION (DRIVER_DESC); | |||
92 | MODULE_LICENSE("GPL"); | 92 | MODULE_LICENSE("GPL"); |
93 | 93 | ||
94 | #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) | 94 | #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) |
95 | #abort "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" | 95 | #error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) | 98 | #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) |
@@ -397,9 +397,11 @@ static int safe_startup (struct usb_serial *serial) | |||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | static struct usb_serial_device_type safe_device = { | 400 | static struct usb_serial_driver safe_device = { |
401 | .owner = THIS_MODULE, | 401 | .driver = { |
402 | .name = "Safe", | 402 | .owner = THIS_MODULE, |
403 | .name = "safe_serial", | ||
404 | }, | ||
403 | .id_table = id_table, | 405 | .id_table = id_table, |
404 | .num_interrupt_in = NUM_DONT_CARE, | 406 | .num_interrupt_in = NUM_DONT_CARE, |
405 | .num_bulk_in = NUM_DONT_CARE, | 407 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 59c88de3e7ae..205dbf7201da 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -255,9 +255,12 @@ static struct usb_driver ti_usb_driver = { | |||
255 | .id_table = ti_id_table_combined, | 255 | .id_table = ti_id_table_combined, |
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct usb_serial_device_type ti_1port_device = { | 258 | static struct usb_serial_driver ti_1port_device = { |
259 | .owner = THIS_MODULE, | 259 | .driver = { |
260 | .name = "TI USB 3410 1 port adapter", | 260 | .owner = THIS_MODULE, |
261 | .name = "ti_usb_3410_5052_1", | ||
262 | }, | ||
263 | .description = "TI USB 3410 1 port adapter", | ||
261 | .id_table = ti_id_table_3410, | 264 | .id_table = ti_id_table_3410, |
262 | .num_interrupt_in = 1, | 265 | .num_interrupt_in = 1, |
263 | .num_bulk_in = 1, | 266 | .num_bulk_in = 1, |
@@ -282,9 +285,12 @@ static struct usb_serial_device_type ti_1port_device = { | |||
282 | .write_bulk_callback = ti_bulk_out_callback, | 285 | .write_bulk_callback = ti_bulk_out_callback, |
283 | }; | 286 | }; |
284 | 287 | ||
285 | static struct usb_serial_device_type ti_2port_device = { | 288 | static struct usb_serial_driver ti_2port_device = { |
286 | .owner = THIS_MODULE, | 289 | .driver = { |
287 | .name = "TI USB 5052 2 port adapter", | 290 | .owner = THIS_MODULE, |
291 | .name = "ti_usb_3410_5052_2", | ||
292 | }, | ||
293 | .description = "TI USB 5052 2 port adapter", | ||
288 | .id_table = ti_id_table_5052, | 294 | .id_table = ti_id_table_5052, |
289 | .num_interrupt_in = 1, | 295 | .num_interrupt_in = 1, |
290 | .num_bulk_in = 2, | 296 | .num_bulk_in = 2, |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index e77fbdfc782d..0c4881d18cd5 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * USB Serial Converter driver | 2 | * USB Serial Converter driver |
3 | * | 3 | * |
4 | * Copyright (C) 1999 - 2004 Greg Kroah-Hartman (greg@kroah.com) | 4 | * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com) |
5 | * Copyright (C) 2000 Peter Berger (pberger@brimson.com) | 5 | * Copyright (C) 2000 Peter Berger (pberger@brimson.com) |
6 | * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) | 6 | * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) |
7 | * | 7 | * |
@@ -9,316 +9,11 @@ | |||
9 | * modify it under the terms of the GNU General Public License version | 9 | * modify it under the terms of the GNU General Public License version |
10 | * 2 as published by the Free Software Foundation. | 10 | * 2 as published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * This driver was originally based on the ACM driver by Armin Fuerst (which was | 12 | * This driver was originally based on the ACM driver by Armin Fuerst (which was |
13 | * based on a driver by Brad Keryan) | 13 | * based on a driver by Brad Keryan) |
14 | * | 14 | * |
15 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 15 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
16 | * | 16 | * |
17 | * (12/10/2002) gkh | ||
18 | * Split the ports off into their own struct device, and added a | ||
19 | * usb-serial bus driver. | ||
20 | * | ||
21 | * (11/19/2002) gkh | ||
22 | * removed a few #ifdefs for the generic code and cleaned up the failure | ||
23 | * logic in initialization. | ||
24 | * | ||
25 | * (10/02/2002) gkh | ||
26 | * moved the console code to console.c and out of this file. | ||
27 | * | ||
28 | * (06/05/2002) gkh | ||
29 | * moved location of startup() call in serial_probe() until after all | ||
30 | * of the port information and endpoints are initialized. This makes | ||
31 | * things easier for some drivers. | ||
32 | * | ||
33 | * (04/10/2002) gkh | ||
34 | * added serial_read_proc function which creates a | ||
35 | * /proc/tty/driver/usb-serial file. | ||
36 | * | ||
37 | * (03/27/2002) gkh | ||
38 | * Got USB serial console code working properly and merged into the main | ||
39 | * version of the tree. Thanks to Randy Dunlap for the initial version | ||
40 | * of this code, and for pushing me to finish it up. | ||
41 | * The USB serial console works with any usb serial driver device. | ||
42 | * | ||
43 | * (03/21/2002) gkh | ||
44 | * Moved all manipulation of port->open_count into the core. Now the | ||
45 | * individual driver's open and close functions are called only when the | ||
46 | * first open() and last close() is called. Making the drivers a bit | ||
47 | * smaller and simpler. | ||
48 | * Fixed a bug if a driver didn't have the owner field set. | ||
49 | * | ||
50 | * (02/26/2002) gkh | ||
51 | * Moved all locking into the main serial_* functions, instead of having | ||
52 | * the individual drivers have to grab the port semaphore. This should | ||
53 | * reduce races. | ||
54 | * Reworked the MOD_INC logic a bit to always increment and decrement, even | ||
55 | * if the generic driver is being used. | ||
56 | * | ||
57 | * (10/10/2001) gkh | ||
58 | * usb_serial_disconnect() now sets the serial->dev pointer is to NULL to | ||
59 | * help prevent child drivers from accessing the device since it is now | ||
60 | * gone. | ||
61 | * | ||
62 | * (09/13/2001) gkh | ||
63 | * Moved generic driver initialize after we have registered with the USB | ||
64 | * core. Thanks to Randy Dunlap for pointing this problem out. | ||
65 | * | ||
66 | * (07/03/2001) gkh | ||
67 | * Fixed module paramater size. Thanks to John Brockmeyer for the pointer. | ||
68 | * Fixed vendor and product getting defined through the MODULE_PARM macro | ||
69 | * if the Generic driver wasn't compiled in. | ||
70 | * Fixed problem with generic_shutdown() not being called for drivers that | ||
71 | * don't have a shutdown() function. | ||
72 | * | ||
73 | * (06/06/2001) gkh | ||
74 | * added evil hack that is needed for the prolific pl2303 device due to the | ||
75 | * crazy way its endpoints are set up. | ||
76 | * | ||
77 | * (05/30/2001) gkh | ||
78 | * switched from using spinlock to a semaphore, which fixes lots of problems. | ||
79 | * | ||
80 | * (04/08/2001) gb | ||
81 | * Identify version on module load. | ||
82 | * | ||
83 | * 2001_02_05 gkh | ||
84 | * Fixed buffer overflows bug with the generic serial driver. Thanks to | ||
85 | * Todd Squires <squirest@ct0.com> for fixing this. | ||
86 | * | ||
87 | * (01/10/2001) gkh | ||
88 | * Fixed bug where the generic serial adaptor grabbed _any_ device that was | ||
89 | * offered to it. | ||
90 | * | ||
91 | * (12/12/2000) gkh | ||
92 | * Removed MOD_INC and MOD_DEC from poll and disconnect functions, and | ||
93 | * moved them to the serial_open and serial_close functions. | ||
94 | * Also fixed bug with there not being a MOD_DEC for the generic driver | ||
95 | * (thanks to Gary Brubaker for finding this.) | ||
96 | * | ||
97 | * (11/29/2000) gkh | ||
98 | * Small NULL pointer initialization cleanup which saves a bit of disk image | ||
99 | * | ||
100 | * (11/01/2000) Adam J. Richter | ||
101 | * instead of using idVendor/idProduct pairs, usb serial drivers | ||
102 | * now identify their hardware interest with usb_device_id tables, | ||
103 | * which they usually have anyhow for use with MODULE_DEVICE_TABLE. | ||
104 | * | ||
105 | * (10/05/2000) gkh | ||
106 | * Fixed bug with urb->dev not being set properly, now that the usb | ||
107 | * core needs it. | ||
108 | * | ||
109 | * (09/11/2000) gkh | ||
110 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
111 | * | ||
112 | * (08/28/2000) gkh | ||
113 | * Added port_lock to port structure. | ||
114 | * Added locks for SMP safeness to generic driver | ||
115 | * Fixed the ability to open a generic device's port more than once. | ||
116 | * | ||
117 | * (07/23/2000) gkh | ||
118 | * Added bulk_out_endpointAddress to port structure. | ||
119 | * | ||
120 | * (07/19/2000) gkh, pberger, and borchers | ||
121 | * Modifications to allow usb-serial drivers to be modules. | ||
122 | * | ||
123 | * (07/03/2000) gkh | ||
124 | * Added more debugging to serial_ioctl call | ||
125 | * | ||
126 | * (06/25/2000) gkh | ||
127 | * Changed generic_write_bulk_callback to not call wake_up_interruptible | ||
128 | * directly, but to have port_softint do it at a safer time. | ||
129 | * | ||
130 | * (06/23/2000) gkh | ||
131 | * Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
132 | * | ||
133 | * (05/22/2000) gkh | ||
134 | * Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be | ||
135 | * removed from the individual device source files. | ||
136 | * | ||
137 | * (05/03/2000) gkh | ||
138 | * Added the Digi Acceleport driver from Al Borchers and Peter Berger. | ||
139 | * | ||
140 | * (05/02/2000) gkh | ||
141 | * Changed devfs and tty register code to work properly now. This was based on | ||
142 | * the ACM driver changes by Vojtech Pavlik. | ||
143 | * | ||
144 | * (04/27/2000) Ryan VanderBijl | ||
145 | * Put calls to *_paranoia_checks into one function. | ||
146 | * | ||
147 | * (04/23/2000) gkh | ||
148 | * Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. | ||
149 | * Moved when the startup code printed out the devices that are supported. | ||
150 | * | ||
151 | * (04/19/2000) gkh | ||
152 | * Added driver for ZyXEL omni.net lcd plus ISDN TA | ||
153 | * Made startup info message specify which drivers were compiled in. | ||
154 | * | ||
155 | * (04/03/2000) gkh | ||
156 | * Changed the probe process to remove the module unload races. | ||
157 | * Changed where the tty layer gets initialized to have devfs work nicer. | ||
158 | * Added initial devfs support. | ||
159 | * | ||
160 | * (03/26/2000) gkh | ||
161 | * Split driver up into device specific pieces. | ||
162 | * | ||
163 | * (03/19/2000) gkh | ||
164 | * Fixed oops that could happen when device was removed while a program | ||
165 | * was talking to the device. | ||
166 | * Removed the static urbs and now all urbs are created and destroyed | ||
167 | * dynamically. | ||
168 | * Reworked the internal interface. Now everything is based on the | ||
169 | * usb_serial_port structure instead of the larger usb_serial structure. | ||
170 | * This fixes the bug that a multiport device could not have more than | ||
171 | * one port open at one time. | ||
172 | * | ||
173 | * (03/17/2000) gkh | ||
174 | * Added config option for debugging messages. | ||
175 | * Added patch for keyspan pda from Brian Warner. | ||
176 | * | ||
177 | * (03/06/2000) gkh | ||
178 | * Added the keyspan pda code from Brian Warner <warner@lothar.com> | ||
179 | * Moved a bunch of the port specific stuff into its own structure. This | ||
180 | * is in anticipation of the true multiport devices (there's a bug if you | ||
181 | * try to access more than one port of any multiport device right now) | ||
182 | * | ||
183 | * (02/21/2000) gkh | ||
184 | * Made it so that any serial devices only have to specify which functions | ||
185 | * they want to overload from the generic function calls (great, | ||
186 | * inheritance in C, in a driver, just what I wanted...) | ||
187 | * Added support for set_termios and ioctl function calls. No drivers take | ||
188 | * advantage of this yet. | ||
189 | * Removed the #ifdef MODULE, now there is no module specific code. | ||
190 | * Cleaned up a few comments in usb-serial.h that were wrong (thanks again | ||
191 | * to Miles Lott). | ||
192 | * Small fix to get_free_serial. | ||
193 | * | ||
194 | * (02/14/2000) gkh | ||
195 | * Removed the Belkin and Peracom functionality from the driver due to | ||
196 | * the lack of support from the vendor, and me not wanting people to | ||
197 | * accidenatly buy the device, expecting it to work with Linux. | ||
198 | * Added read_bulk_callback and write_bulk_callback to the type structure | ||
199 | * for the needs of the FTDI and WhiteHEAT driver. | ||
200 | * Changed all reverences to FTDI to FTDI_SIO at the request of Bill | ||
201 | * Ryder. | ||
202 | * Changed the output urb size back to the max endpoint size to make | ||
203 | * the ftdi_sio driver have it easier, and due to the fact that it didn't | ||
204 | * really increase the speed any. | ||
205 | * | ||
206 | * (02/11/2000) gkh | ||
207 | * Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a | ||
208 | * patch from Miles Lott (milos@insync.net). | ||
209 | * Fixed bug with not restoring the minor range that a device grabs, if | ||
210 | * the startup function fails (thanks Miles for finding this). | ||
211 | * | ||
212 | * (02/05/2000) gkh | ||
213 | * Added initial framework for the Keyspan PDA serial converter so that | ||
214 | * Brian Warner has a place to put his code. | ||
215 | * Made the ezusb specific functions generic enough that different | ||
216 | * devices can use them (whiteheat and keyspan_pda both need them). | ||
217 | * Split out a whole bunch of structure and other stuff to a separate | ||
218 | * usb-serial.h file. | ||
219 | * Made the Visor connection messages a little more understandable, now | ||
220 | * that Miles Lott (milos@insync.net) has gotten the Generic channel to | ||
221 | * work. Also made them always show up in the log file. | ||
222 | * | ||
223 | * (01/25/2000) gkh | ||
224 | * Added initial framework for FTDI serial converter so that Bill Ryder | ||
225 | * has a place to put his code. | ||
226 | * Added the vendor specific info from Handspring. Now we can print out | ||
227 | * informational debug messages as well as understand what is happening. | ||
228 | * | ||
229 | * (01/23/2000) gkh | ||
230 | * Fixed problem of crash when trying to open a port that didn't have a | ||
231 | * device assigned to it. Made the minor node finding a little smarter, | ||
232 | * now it looks to find a continuous space for the new device. | ||
233 | * | ||
234 | * (01/21/2000) gkh | ||
235 | * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) | ||
236 | * Fixed get_serial_by_minor which was all messed up for multi port | ||
237 | * devices. Fixed multi port problem for generic devices. Now the number | ||
238 | * of ports is determined by the number of bulk out endpoints for the | ||
239 | * generic device. | ||
240 | * | ||
241 | * (01/19/2000) gkh | ||
242 | * Removed lots of cruft that was around from the old (pre urb) driver | ||
243 | * interface. | ||
244 | * Made the serial_table dynamic. This should save lots of memory when | ||
245 | * the number of minor nodes goes up to 256. | ||
246 | * Added initial support for devices that have more than one port. | ||
247 | * Added more debugging comments for the Visor, and added a needed | ||
248 | * set_configuration call. | ||
249 | * | ||
250 | * (01/17/2000) gkh | ||
251 | * Fixed the WhiteHEAT firmware (my processing tool had a bug) | ||
252 | * and added new debug loader firmware for it. | ||
253 | * Removed the put_char function as it isn't really needed. | ||
254 | * Added visor startup commands as found by the Win98 dump. | ||
255 | * | ||
256 | * (01/13/2000) gkh | ||
257 | * Fixed the vendor id for the generic driver to the one I meant it to be. | ||
258 | * | ||
259 | * (01/12/2000) gkh | ||
260 | * Forget the version numbering...that's pretty useless... | ||
261 | * Made the driver able to be compiled so that the user can select which | ||
262 | * converter they want to use. This allows people who only want the Visor | ||
263 | * support to not pay the memory size price of the WhiteHEAT. | ||
264 | * Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) | ||
265 | * grabbed the root hub. Not good. | ||
266 | * | ||
267 | * version 0.4.0 (01/10/2000) gkh | ||
268 | * Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT | ||
269 | * device. Added startup function to allow firmware to be downloaded to | ||
270 | * a device if it needs to be. | ||
271 | * Added firmware download logic to the WhiteHEAT device. | ||
272 | * Started to add #defines to split up the different drivers for potential | ||
273 | * configuration option. | ||
274 | * | ||
275 | * version 0.3.1 (12/30/99) gkh | ||
276 | * Fixed problems with urb for bulk out. | ||
277 | * Added initial support for multiple sets of endpoints. This enables | ||
278 | * the Handspring Visor to be attached successfully. Only the first | ||
279 | * bulk in / bulk out endpoint pair is being used right now. | ||
280 | * | ||
281 | * version 0.3.0 (12/27/99) gkh | ||
282 | * Added initial support for the Handspring Visor based on a patch from | ||
283 | * Miles Lott (milos@sneety.insync.net) | ||
284 | * Cleaned up the code a bunch and converted over to using urbs only. | ||
285 | * | ||
286 | * version 0.2.3 (12/21/99) gkh | ||
287 | * Added initial support for the Connect Tech WhiteHEAT converter. | ||
288 | * Incremented the number of ports in expectation of getting the | ||
289 | * WhiteHEAT to work properly (4 ports per connection). | ||
290 | * Added notification on insertion and removal of what port the | ||
291 | * device is/was connected to (and what kind of device it was). | ||
292 | * | ||
293 | * version 0.2.2 (12/16/99) gkh | ||
294 | * Changed major number to the new allocated number. We're legal now! | ||
295 | * | ||
296 | * version 0.2.1 (12/14/99) gkh | ||
297 | * Fixed bug that happens when device node is opened when there isn't a | ||
298 | * device attached to it. Thanks to marek@webdesign.no for noticing this. | ||
299 | * | ||
300 | * version 0.2.0 (11/10/99) gkh | ||
301 | * Split up internals to make it easier to add different types of serial | ||
302 | * converters to the code. | ||
303 | * Added a "generic" driver that gets it's vendor and product id | ||
304 | * from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) | ||
305 | * for the idea and sample code (from the usb scanner driver.) | ||
306 | * Cleared up any licensing questions by releasing it under the GNU GPL. | ||
307 | * | ||
308 | * version 0.1.2 (10/25/99) gkh | ||
309 | * Fixed bug in detecting device. | ||
310 | * | ||
311 | * version 0.1.1 (10/05/99) gkh | ||
312 | * Changed the major number to not conflict with anything else. | ||
313 | * | ||
314 | * version 0.1 (09/28/99) gkh | ||
315 | * Can recognize the two different devices and start up a read from | ||
316 | * device when asked to. Writes also work. No control signals yet, this | ||
317 | * all is vendor specific data (i.e. no spec), also no control for | ||
318 | * different baud rates or other bit settings. | ||
319 | * Currently we are using the same devid as the acm driver. This needs | ||
320 | * to change. | ||
321 | * | ||
322 | */ | 17 | */ |
323 | 18 | ||
324 | #include <linux/config.h> | 19 | #include <linux/config.h> |
@@ -342,7 +37,6 @@ | |||
342 | /* | 37 | /* |
343 | * Version Information | 38 | * Version Information |
344 | */ | 39 | */ |
345 | #define DRIVER_VERSION "v2.0" | ||
346 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" | 40 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" |
347 | #define DRIVER_DESC "USB Serial Driver core" | 41 | #define DRIVER_DESC "USB Serial Driver core" |
348 | 42 | ||
@@ -427,7 +121,7 @@ static void destroy_serial(struct kref *kref) | |||
427 | 121 | ||
428 | serial = to_usb_serial(kref); | 122 | serial = to_usb_serial(kref); |
429 | 123 | ||
430 | dbg ("%s - %s", __FUNCTION__, serial->type->name); | 124 | dbg("%s - %s", __FUNCTION__, serial->type->description); |
431 | 125 | ||
432 | serial->type->shutdown(serial); | 126 | serial->type->shutdown(serial); |
433 | 127 | ||
@@ -507,7 +201,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
507 | /* lock this module before we call it | 201 | /* lock this module before we call it |
508 | * this may fail, which means we must bail out, | 202 | * this may fail, which means we must bail out, |
509 | * safe because we are called with BKL held */ | 203 | * safe because we are called with BKL held */ |
510 | if (!try_module_get(serial->type->owner)) { | 204 | if (!try_module_get(serial->type->driver.owner)) { |
511 | retval = -ENODEV; | 205 | retval = -ENODEV; |
512 | goto bailout_kref_put; | 206 | goto bailout_kref_put; |
513 | } | 207 | } |
@@ -522,7 +216,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
522 | return 0; | 216 | return 0; |
523 | 217 | ||
524 | bailout_module_put: | 218 | bailout_module_put: |
525 | module_put(serial->type->owner); | 219 | module_put(serial->type->driver.owner); |
526 | bailout_kref_put: | 220 | bailout_kref_put: |
527 | kref_put(&serial->kref, destroy_serial); | 221 | kref_put(&serial->kref, destroy_serial); |
528 | port->open_count = 0; | 222 | port->open_count = 0; |
@@ -553,7 +247,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
553 | port->tty = NULL; | 247 | port->tty = NULL; |
554 | } | 248 | } |
555 | 249 | ||
556 | module_put(port->serial->type->owner); | 250 | module_put(port->serial->type->driver.owner); |
557 | } | 251 | } |
558 | 252 | ||
559 | kref_put(&port->serial->kref, destroy_serial); | 253 | kref_put(&port->serial->kref, destroy_serial); |
@@ -711,16 +405,16 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int | |||
711 | char tmp[40]; | 405 | char tmp[40]; |
712 | 406 | ||
713 | dbg("%s", __FUNCTION__); | 407 | dbg("%s", __FUNCTION__); |
714 | length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION); | 408 | length += sprintf (page, "usbserinfo:1.0 driver:2.0\n"); |
715 | for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { | 409 | for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) { |
716 | serial = usb_serial_get_by_index(i); | 410 | serial = usb_serial_get_by_index(i); |
717 | if (serial == NULL) | 411 | if (serial == NULL) |
718 | continue; | 412 | continue; |
719 | 413 | ||
720 | length += sprintf (page+length, "%d:", i); | 414 | length += sprintf (page+length, "%d:", i); |
721 | if (serial->type->owner) | 415 | if (serial->type->driver.owner) |
722 | length += sprintf (page+length, " module:%s", module_name(serial->type->owner)); | 416 | length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner)); |
723 | length += sprintf (page+length, " name:\"%s\"", serial->type->name); | 417 | length += sprintf (page+length, " name:\"%s\"", serial->type->description); |
724 | length += sprintf (page+length, " vendor:%04x product:%04x", | 418 | length += sprintf (page+length, " vendor:%04x product:%04x", |
725 | le16_to_cpu(serial->dev->descriptor.idVendor), | 419 | le16_to_cpu(serial->dev->descriptor.idVendor), |
726 | le16_to_cpu(serial->dev->descriptor.idProduct)); | 420 | le16_to_cpu(serial->dev->descriptor.idProduct)); |
@@ -823,7 +517,7 @@ static void port_release(struct device *dev) | |||
823 | 517 | ||
824 | static struct usb_serial * create_serial (struct usb_device *dev, | 518 | static struct usb_serial * create_serial (struct usb_device *dev, |
825 | struct usb_interface *interface, | 519 | struct usb_interface *interface, |
826 | struct usb_serial_device_type *type) | 520 | struct usb_serial_driver *driver) |
827 | { | 521 | { |
828 | struct usb_serial *serial; | 522 | struct usb_serial *serial; |
829 | 523 | ||
@@ -834,22 +528,22 @@ static struct usb_serial * create_serial (struct usb_device *dev, | |||
834 | } | 528 | } |
835 | memset (serial, 0, sizeof(*serial)); | 529 | memset (serial, 0, sizeof(*serial)); |
836 | serial->dev = usb_get_dev(dev); | 530 | serial->dev = usb_get_dev(dev); |
837 | serial->type = type; | 531 | serial->type = driver; |
838 | serial->interface = interface; | 532 | serial->interface = interface; |
839 | kref_init(&serial->kref); | 533 | kref_init(&serial->kref); |
840 | 534 | ||
841 | return serial; | 535 | return serial; |
842 | } | 536 | } |
843 | 537 | ||
844 | static struct usb_serial_device_type *search_serial_device(struct usb_interface *iface) | 538 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
845 | { | 539 | { |
846 | struct list_head *p; | 540 | struct list_head *p; |
847 | const struct usb_device_id *id; | 541 | const struct usb_device_id *id; |
848 | struct usb_serial_device_type *t; | 542 | struct usb_serial_driver *t; |
849 | 543 | ||
850 | /* List trough know devices and see if the usb id matches */ | 544 | /* List trough know devices and see if the usb id matches */ |
851 | list_for_each(p, &usb_serial_driver_list) { | 545 | list_for_each(p, &usb_serial_driver_list) { |
852 | t = list_entry(p, struct usb_serial_device_type, driver_list); | 546 | t = list_entry(p, struct usb_serial_driver, driver_list); |
853 | id = usb_match_id(iface, t->id_table); | 547 | id = usb_match_id(iface, t->id_table); |
854 | if (id != NULL) { | 548 | if (id != NULL) { |
855 | dbg("descriptor matches"); | 549 | dbg("descriptor matches"); |
@@ -872,7 +566,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
872 | struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS]; | 566 | struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS]; |
873 | struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; | 567 | struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS]; |
874 | struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; | 568 | struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS]; |
875 | struct usb_serial_device_type *type = NULL; | 569 | struct usb_serial_driver *type = NULL; |
876 | int retval; | 570 | int retval; |
877 | int minor; | 571 | int minor; |
878 | int buffer_size; | 572 | int buffer_size; |
@@ -900,7 +594,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
900 | if (type->probe) { | 594 | if (type->probe) { |
901 | const struct usb_device_id *id; | 595 | const struct usb_device_id *id; |
902 | 596 | ||
903 | if (!try_module_get(type->owner)) { | 597 | if (!try_module_get(type->driver.owner)) { |
904 | dev_err(&interface->dev, "module get failed, exiting\n"); | 598 | dev_err(&interface->dev, "module get failed, exiting\n"); |
905 | kfree (serial); | 599 | kfree (serial); |
906 | return -EIO; | 600 | return -EIO; |
@@ -908,7 +602,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
908 | 602 | ||
909 | id = usb_match_id(interface, type->id_table); | 603 | id = usb_match_id(interface, type->id_table); |
910 | retval = type->probe(serial, id); | 604 | retval = type->probe(serial, id); |
911 | module_put(type->owner); | 605 | module_put(type->driver.owner); |
912 | 606 | ||
913 | if (retval) { | 607 | if (retval) { |
914 | dbg ("sub driver rejected device"); | 608 | dbg ("sub driver rejected device"); |
@@ -992,7 +686,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
992 | #endif | 686 | #endif |
993 | 687 | ||
994 | /* found all that we need */ | 688 | /* found all that we need */ |
995 | dev_info(&interface->dev, "%s converter detected\n", type->name); | 689 | dev_info(&interface->dev, "%s converter detected\n", type->description); |
996 | 690 | ||
997 | #ifdef CONFIG_USB_SERIAL_GENERIC | 691 | #ifdef CONFIG_USB_SERIAL_GENERIC |
998 | if (type == &usb_serial_generic_device) { | 692 | if (type == &usb_serial_generic_device) { |
@@ -1007,13 +701,13 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1007 | if (!num_ports) { | 701 | if (!num_ports) { |
1008 | /* if this device type has a calc_num_ports function, call it */ | 702 | /* if this device type has a calc_num_ports function, call it */ |
1009 | if (type->calc_num_ports) { | 703 | if (type->calc_num_ports) { |
1010 | if (!try_module_get(type->owner)) { | 704 | if (!try_module_get(type->driver.owner)) { |
1011 | dev_err(&interface->dev, "module get failed, exiting\n"); | 705 | dev_err(&interface->dev, "module get failed, exiting\n"); |
1012 | kfree (serial); | 706 | kfree (serial); |
1013 | return -EIO; | 707 | return -EIO; |
1014 | } | 708 | } |
1015 | num_ports = type->calc_num_ports (serial); | 709 | num_ports = type->calc_num_ports (serial); |
1016 | module_put(type->owner); | 710 | module_put(type->driver.owner); |
1017 | } | 711 | } |
1018 | if (!num_ports) | 712 | if (!num_ports) |
1019 | num_ports = type->num_ports; | 713 | num_ports = type->num_ports; |
@@ -1158,12 +852,12 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1158 | 852 | ||
1159 | /* if this device type has an attach function, call it */ | 853 | /* if this device type has an attach function, call it */ |
1160 | if (type->attach) { | 854 | if (type->attach) { |
1161 | if (!try_module_get(type->owner)) { | 855 | if (!try_module_get(type->driver.owner)) { |
1162 | dev_err(&interface->dev, "module get failed, exiting\n"); | 856 | dev_err(&interface->dev, "module get failed, exiting\n"); |
1163 | goto probe_error; | 857 | goto probe_error; |
1164 | } | 858 | } |
1165 | retval = type->attach (serial); | 859 | retval = type->attach (serial); |
1166 | module_put(type->owner); | 860 | module_put(type->driver.owner); |
1167 | if (retval < 0) | 861 | if (retval < 0) |
1168 | goto probe_error; | 862 | goto probe_error; |
1169 | if (retval > 0) { | 863 | if (retval > 0) { |
@@ -1330,7 +1024,7 @@ static int __init usb_serial_init(void) | |||
1330 | goto exit_generic; | 1024 | goto exit_generic; |
1331 | } | 1025 | } |
1332 | 1026 | ||
1333 | info(DRIVER_DESC " " DRIVER_VERSION); | 1027 | info(DRIVER_DESC); |
1334 | 1028 | ||
1335 | return result; | 1029 | return result; |
1336 | 1030 | ||
@@ -1375,7 +1069,7 @@ module_exit(usb_serial_exit); | |||
1375 | } \ | 1069 | } \ |
1376 | } while (0) | 1070 | } while (0) |
1377 | 1071 | ||
1378 | static void fixup_generic(struct usb_serial_device_type *device) | 1072 | static void fixup_generic(struct usb_serial_driver *device) |
1379 | { | 1073 | { |
1380 | set_to_generic_if_null(device, open); | 1074 | set_to_generic_if_null(device, open); |
1381 | set_to_generic_if_null(device, write); | 1075 | set_to_generic_if_null(device, write); |
@@ -1387,30 +1081,33 @@ static void fixup_generic(struct usb_serial_device_type *device) | |||
1387 | set_to_generic_if_null(device, shutdown); | 1081 | set_to_generic_if_null(device, shutdown); |
1388 | } | 1082 | } |
1389 | 1083 | ||
1390 | int usb_serial_register(struct usb_serial_device_type *new_device) | 1084 | int usb_serial_register(struct usb_serial_driver *driver) |
1391 | { | 1085 | { |
1392 | int retval; | 1086 | int retval; |
1393 | 1087 | ||
1394 | fixup_generic(new_device); | 1088 | fixup_generic(driver); |
1089 | |||
1090 | if (!driver->description) | ||
1091 | driver->description = driver->driver.name; | ||
1395 | 1092 | ||
1396 | /* Add this device to our list of devices */ | 1093 | /* Add this device to our list of devices */ |
1397 | list_add(&new_device->driver_list, &usb_serial_driver_list); | 1094 | list_add(&driver->driver_list, &usb_serial_driver_list); |
1398 | 1095 | ||
1399 | retval = usb_serial_bus_register(new_device); | 1096 | retval = usb_serial_bus_register(driver); |
1400 | if (retval) { | 1097 | if (retval) { |
1401 | err("problem %d when registering driver %s", retval, new_device->name); | 1098 | err("problem %d when registering driver %s", retval, driver->description); |
1402 | list_del(&new_device->driver_list); | 1099 | list_del(&driver->driver_list); |
1403 | } | 1100 | } |
1404 | else | 1101 | else |
1405 | info("USB Serial support registered for %s", new_device->name); | 1102 | info("USB Serial support registered for %s", driver->description); |
1406 | 1103 | ||
1407 | return retval; | 1104 | return retval; |
1408 | } | 1105 | } |
1409 | 1106 | ||
1410 | 1107 | ||
1411 | void usb_serial_deregister(struct usb_serial_device_type *device) | 1108 | void usb_serial_deregister(struct usb_serial_driver *device) |
1412 | { | 1109 | { |
1413 | info("USB Serial deregistering driver %s", device->name); | 1110 | info("USB Serial deregistering driver %s", device->description); |
1414 | list_del(&device->driver_list); | 1111 | list_del(&device->driver_list); |
1415 | usb_serial_bus_deregister(device); | 1112 | usb_serial_bus_deregister(device); |
1416 | } | 1113 | } |
@@ -1429,7 +1126,6 @@ EXPORT_SYMBOL_GPL(usb_serial_port_softint); | |||
1429 | /* Module information */ | 1126 | /* Module information */ |
1430 | MODULE_AUTHOR( DRIVER_AUTHOR ); | 1127 | MODULE_AUTHOR( DRIVER_AUTHOR ); |
1431 | MODULE_DESCRIPTION( DRIVER_DESC ); | 1128 | MODULE_DESCRIPTION( DRIVER_DESC ); |
1432 | MODULE_VERSION( DRIVER_VERSION ); | ||
1433 | MODULE_LICENSE("GPL"); | 1129 | MODULE_LICENSE("GPL"); |
1434 | 1130 | ||
1435 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 1131 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 57f92f054c75..238a5a871ed6 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h | |||
@@ -1,53 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * USB Serial Converter driver | 2 | * USB Serial Converter driver |
3 | * | 3 | * |
4 | * Copyright (C) 1999 - 2004 | 4 | * Copyright (C) 1999 - 2005 |
5 | * Greg Kroah-Hartman (greg@kroah.com) | 5 | * Greg Kroah-Hartman (greg@kroah.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License. |
10 | * (at your option) any later version. | ||
11 | * | 10 | * |
12 | * See Documentation/usb/usb-serial.txt for more information on using this driver | ||
13 | * | ||
14 | * (03/26/2002) gkh | ||
15 | * removed the port->tty check from port_paranoia_check() due to serial | ||
16 | * consoles not having a tty device assigned to them. | ||
17 | * | ||
18 | * (12/03/2001) gkh | ||
19 | * removed active from the port structure. | ||
20 | * added documentation to the usb_serial_device_type structure | ||
21 | * | ||
22 | * (10/10/2001) gkh | ||
23 | * added vendor and product to serial structure. Needed to determine device | ||
24 | * owner when the device is disconnected. | ||
25 | * | ||
26 | * (05/30/2001) gkh | ||
27 | * added sem to port structure and removed port_lock | ||
28 | * | ||
29 | * (10/05/2000) gkh | ||
30 | * Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help | ||
31 | * fix bug with urb->dev not being set properly, now that the usb core | ||
32 | * needs it. | ||
33 | * | ||
34 | * (09/11/2000) gkh | ||
35 | * Added usb_serial_debug_data function to help get rid of #DEBUG in the | ||
36 | * drivers. | ||
37 | * | ||
38 | * (08/28/2000) gkh | ||
39 | * Added port_lock to port structure. | ||
40 | * | ||
41 | * (08/08/2000) gkh | ||
42 | * Added open_count to port structure. | ||
43 | * | ||
44 | * (07/23/2000) gkh | ||
45 | * Added bulk_out_endpointAddress to port structure. | ||
46 | * | ||
47 | * (07/19/2000) gkh, pberger, and borchers | ||
48 | * Modifications to allow usb-serial drivers to be modules. | ||
49 | * | ||
50 | * | ||
51 | */ | 11 | */ |
52 | 12 | ||
53 | 13 | ||
@@ -143,7 +103,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void | |||
143 | /** | 103 | /** |
144 | * usb_serial - structure used by the usb-serial core for a device | 104 | * usb_serial - structure used by the usb-serial core for a device |
145 | * @dev: pointer to the struct usb_device for this device | 105 | * @dev: pointer to the struct usb_device for this device |
146 | * @type: pointer to the struct usb_serial_device_type for this device | 106 | * @type: pointer to the struct usb_serial_driver for this device |
147 | * @interface: pointer to the struct usb_interface for this device | 107 | * @interface: pointer to the struct usb_interface for this device |
148 | * @minor: the starting minor number for this device | 108 | * @minor: the starting minor number for this device |
149 | * @num_ports: the number of ports this device has | 109 | * @num_ports: the number of ports this device has |
@@ -159,7 +119,7 @@ static inline void usb_set_serial_port_data (struct usb_serial_port *port, void | |||
159 | */ | 119 | */ |
160 | struct usb_serial { | 120 | struct usb_serial { |
161 | struct usb_device * dev; | 121 | struct usb_device * dev; |
162 | struct usb_serial_device_type * type; | 122 | struct usb_serial_driver * type; |
163 | struct usb_interface * interface; | 123 | struct usb_interface * interface; |
164 | unsigned char minor; | 124 | unsigned char minor; |
165 | unsigned char num_ports; | 125 | unsigned char num_ports; |
@@ -188,13 +148,9 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) | |||
188 | } | 148 | } |
189 | 149 | ||
190 | /** | 150 | /** |
191 | * usb_serial_device_type - a structure that defines a usb serial device | 151 | * usb_serial_driver - describes a usb serial driver |
192 | * @owner: pointer to the module that owns this device. | 152 | * @description: pointer to a string that describes this driver. This string used |
193 | * @name: pointer to a string that describes this device. This string used | ||
194 | * in the syslog messages when a device is inserted or removed. | 153 | * in the syslog messages when a device is inserted or removed. |
195 | * @short_name: a pointer to a string that describes this device in | ||
196 | * KOBJ_NAME_LEN characters or less. This is used for the sysfs interface | ||
197 | * to describe the driver. | ||
198 | * @id_table: pointer to a list of usb_device_id structures that define all | 154 | * @id_table: pointer to a list of usb_device_id structures that define all |
199 | * of the devices this structure can support. | 155 | * of the devices this structure can support. |
200 | * @num_interrupt_in: the number of interrupt in endpoints this device will | 156 | * @num_interrupt_in: the number of interrupt in endpoints this device will |
@@ -221,16 +177,19 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) | |||
221 | * @shutdown: pointer to the driver's shutdown function. This will be | 177 | * @shutdown: pointer to the driver's shutdown function. This will be |
222 | * called when the device is removed from the system. | 178 | * called when the device is removed from the system. |
223 | * | 179 | * |
224 | * This structure is defines a USB Serial device. It provides all of | 180 | * This structure is defines a USB Serial driver. It provides all of |
225 | * the information that the USB serial core code needs. If the function | 181 | * the information that the USB serial core code needs. If the function |
226 | * pointers are defined, then the USB serial core code will call them when | 182 | * pointers are defined, then the USB serial core code will call them when |
227 | * the corresponding tty port functions are called. If they are not | 183 | * the corresponding tty port functions are called. If they are not |
228 | * called, the generic serial function will be used instead. | 184 | * called, the generic serial function will be used instead. |
185 | * | ||
186 | * The driver.owner field should be set to the module owner of this driver. | ||
187 | * The driver.name field should be set to the name of this driver (remember | ||
188 | * it will show up in sysfs, so it needs to be short and to the point. | ||
189 | * Useing the module name is a good idea.) | ||
229 | */ | 190 | */ |
230 | struct usb_serial_device_type { | 191 | struct usb_serial_driver { |
231 | struct module *owner; | 192 | const char *description; |
232 | char *name; | ||
233 | char *short_name; | ||
234 | const struct usb_device_id *id_table; | 193 | const struct usb_device_id *id_table; |
235 | char num_interrupt_in; | 194 | char num_interrupt_in; |
236 | char num_interrupt_out; | 195 | char num_interrupt_out; |
@@ -269,10 +228,10 @@ struct usb_serial_device_type { | |||
269 | void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs); | 228 | void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs); |
270 | void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs); | 229 | void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs); |
271 | }; | 230 | }; |
272 | #define to_usb_serial_driver(d) container_of(d, struct usb_serial_device_type, driver) | 231 | #define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver) |
273 | 232 | ||
274 | extern int usb_serial_register(struct usb_serial_device_type *new_device); | 233 | extern int usb_serial_register(struct usb_serial_driver *driver); |
275 | extern void usb_serial_deregister(struct usb_serial_device_type *device); | 234 | extern void usb_serial_deregister(struct usb_serial_driver *driver); |
276 | extern void usb_serial_port_softint(void *private); | 235 | extern void usb_serial_port_softint(void *private); |
277 | 236 | ||
278 | extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); | 237 | extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id); |
@@ -303,10 +262,10 @@ extern void usb_serial_generic_shutdown (struct usb_serial *serial); | |||
303 | extern int usb_serial_generic_register (int debug); | 262 | extern int usb_serial_generic_register (int debug); |
304 | extern void usb_serial_generic_deregister (void); | 263 | extern void usb_serial_generic_deregister (void); |
305 | 264 | ||
306 | extern int usb_serial_bus_register (struct usb_serial_device_type *device); | 265 | extern int usb_serial_bus_register (struct usb_serial_driver *device); |
307 | extern void usb_serial_bus_deregister (struct usb_serial_device_type *device); | 266 | extern void usb_serial_bus_deregister (struct usb_serial_driver *device); |
308 | 267 | ||
309 | extern struct usb_serial_device_type usb_serial_generic_device; | 268 | extern struct usb_serial_driver usb_serial_generic_device; |
310 | extern struct bus_type usb_serial_bus_type; | 269 | extern struct bus_type usb_serial_bus_type; |
311 | extern struct tty_driver *usb_serial_tty_driver; | 270 | extern struct tty_driver *usb_serial_tty_driver; |
312 | 271 | ||
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 31c57adcb623..a473c1c34559 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -7,139 +7,10 @@ | |||
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License. |
11 | * (at your option) any later version. | ||
12 | * | 11 | * |
13 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 12 | * See Documentation/usb/usb-serial.txt for more information on using this driver |
14 | * | 13 | * |
15 | * (06/03/2003) Judd Montgomery <judd at jpilot.org> | ||
16 | * Added support for module parameter options for untested/unknown | ||
17 | * devices. | ||
18 | * | ||
19 | * (03/09/2003) gkh | ||
20 | * Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl | ||
21 | * <brachtl@redgrep.cz> for the information. | ||
22 | * | ||
23 | * (03/05/2003) gkh | ||
24 | * Think Treo support is now working. | ||
25 | * | ||
26 | * (04/03/2002) gkh | ||
27 | * Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI | ||
28 | * <hiro@zob.ne.jp> for the information. | ||
29 | * | ||
30 | * (03/27/2002) gkh | ||
31 | * Removed assumptions that port->tty was always valid (is not true | ||
32 | * for usb serial console devices.) | ||
33 | * | ||
34 | * (03/23/2002) gkh | ||
35 | * Added support for the Palm i705 device, thanks to Thomas Riemer | ||
36 | * <tom@netmech.com> for the information. | ||
37 | * | ||
38 | * (03/21/2002) gkh | ||
39 | * Added support for the Palm m130 device, thanks to Udo Eisenbarth | ||
40 | * <udo.eisenbarth@web.de> for the information. | ||
41 | * | ||
42 | * (02/27/2002) gkh | ||
43 | * Reworked the urb handling logic. We have no more pool, but dynamically | ||
44 | * allocate the urb and the transfer buffer on the fly. In testing this | ||
45 | * does not incure any measurable overhead. This also relies on the fact | ||
46 | * that we have proper reference counting logic for urbs. | ||
47 | * | ||
48 | * (02/21/2002) SilaS | ||
49 | * Added initial support for the Palm m515 devices. | ||
50 | * | ||
51 | * (02/14/2002) gkh | ||
52 | * Added support for the Clie S-360 device. | ||
53 | * | ||
54 | * (12/18/2001) gkh | ||
55 | * Added better Clie support for 3.5 devices. Thanks to Geoffrey Levand | ||
56 | * for the patch. | ||
57 | * | ||
58 | * (11/11/2001) gkh | ||
59 | * Added support for the m125 devices, and added check to prevent oopses | ||
60 | * for Clié devices that lie about the number of ports they have. | ||
61 | * | ||
62 | * (08/30/2001) gkh | ||
63 | * Added support for the Clie devices, both the 3.5 and 4.0 os versions. | ||
64 | * Many thanks to Daniel Burke, and Bryan Payne for helping with this. | ||
65 | * | ||
66 | * (08/23/2001) gkh | ||
67 | * fixed a few potential bugs pointed out by Oliver Neukum. | ||
68 | * | ||
69 | * (05/30/2001) gkh | ||
70 | * switched from using spinlock to a semaphore, which fixes lots of problems. | ||
71 | * | ||
72 | * (05/28/2000) gkh | ||
73 | * Added initial support for the Palm m500 and Palm m505 devices. | ||
74 | * | ||
75 | * (04/08/2001) gb | ||
76 | * Identify version on module load. | ||
77 | * | ||
78 | * (01/21/2000) gkh | ||
79 | * Added write_room and chars_in_buffer, as they were previously using the | ||
80 | * generic driver versions which is all wrong now that we are using an urb | ||
81 | * pool. Thanks to Wolfgang Grandegger for pointing this out to me. | ||
82 | * Removed count assignment in the write function, which was not needed anymore | ||
83 | * either. Thanks to Al Borchers for pointing this out. | ||
84 | * | ||
85 | * (12/12/2000) gkh | ||
86 | * Moved MOD_DEC to end of visor_close to be nicer, as the final write | ||
87 | * message can sleep. | ||
88 | * | ||
89 | * (11/12/2000) gkh | ||
90 | * Fixed bug with data being dropped on the floor by forcing tty->low_latency | ||
91 | * to be on. Hopefully this fixes the OHCI issue! | ||
92 | * | ||
93 | * (11/01/2000) Adam J. Richter | ||
94 | * usb_device_id table support | ||
95 | * | ||
96 | * (10/05/2000) gkh | ||
97 | * Fixed bug with urb->dev not being set properly, now that the usb | ||
98 | * core needs it. | ||
99 | * | ||
100 | * (09/11/2000) gkh | ||
101 | * Got rid of always calling kmalloc for every urb we wrote out to the | ||
102 | * device. | ||
103 | * Added visor_read_callback so we can keep track of bytes in and out for | ||
104 | * those people who like to know the speed of their device. | ||
105 | * Removed DEBUG #ifdefs with call to usb_serial_debug_data | ||
106 | * | ||
107 | * (09/06/2000) gkh | ||
108 | * Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_ | ||
109 | * the host controller drivers set urb->dev = NULL when the urb is finished. | ||
110 | * | ||
111 | * (08/28/2000) gkh | ||
112 | * Added locks for SMP safeness. | ||
113 | * | ||
114 | * (08/08/2000) gkh | ||
115 | * Fixed endian problem in visor_startup. | ||
116 | * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more | ||
117 | * than once. | ||
118 | * | ||
119 | * (07/23/2000) gkh | ||
120 | * Added pool of write urbs to speed up transfers to the visor. | ||
121 | * | ||
122 | * (07/19/2000) gkh | ||
123 | * Added module_init and module_exit functions to handle the fact that this | ||
124 | * driver is a loadable module now. | ||
125 | * | ||
126 | * (07/03/2000) gkh | ||
127 | * Added visor_set_ioctl and visor_set_termios functions (they don't do much | ||
128 | * of anything, but are good for debugging.) | ||
129 | * | ||
130 | * (06/25/2000) gkh | ||
131 | * Fixed bug in visor_unthrottle that should help with the disconnect in PPP | ||
132 | * bug that people have been reporting. | ||
133 | * | ||
134 | * (06/23/2000) gkh | ||
135 | * Cleaned up debugging statements in a quest to find UHCI timeout bug. | ||
136 | * | ||
137 | * (04/27/2000) Ryan VanderBijl | ||
138 | * Fixed memory leak in visor_close | ||
139 | * | ||
140 | * (03/26/2000) gkh | ||
141 | * Split driver up into device specific pieces. | ||
142 | * | ||
143 | */ | 14 | */ |
144 | 15 | ||
145 | #include <linux/config.h> | 16 | #include <linux/config.h> |
@@ -161,7 +32,6 @@ | |||
161 | /* | 32 | /* |
162 | * Version Information | 33 | * Version Information |
163 | */ | 34 | */ |
164 | #define DRIVER_VERSION "v2.1" | ||
165 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" | 35 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" |
166 | #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" | 36 | #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver" |
167 | 37 | ||
@@ -311,10 +181,12 @@ static struct usb_driver visor_driver = { | |||
311 | }; | 181 | }; |
312 | 182 | ||
313 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ | 183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ |
314 | static struct usb_serial_device_type handspring_device = { | 184 | static struct usb_serial_driver handspring_device = { |
315 | .owner = THIS_MODULE, | 185 | .driver = { |
316 | .name = "Handspring Visor / Palm OS", | 186 | .owner = THIS_MODULE, |
317 | .short_name = "visor", | 187 | .name = "visor", |
188 | }, | ||
189 | .description = "Handspring Visor / Palm OS", | ||
318 | .id_table = id_table, | 190 | .id_table = id_table, |
319 | .num_interrupt_in = NUM_DONT_CARE, | 191 | .num_interrupt_in = NUM_DONT_CARE, |
320 | .num_bulk_in = 2, | 192 | .num_bulk_in = 2, |
@@ -339,10 +211,12 @@ static struct usb_serial_device_type handspring_device = { | |||
339 | }; | 211 | }; |
340 | 212 | ||
341 | /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ | 213 | /* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */ |
342 | static struct usb_serial_device_type clie_5_device = { | 214 | static struct usb_serial_driver clie_5_device = { |
343 | .owner = THIS_MODULE, | 215 | .driver = { |
344 | .name = "Sony Clie 5.0", | 216 | .owner = THIS_MODULE, |
345 | .short_name = "clie_5", | 217 | .name = "clie_5", |
218 | }, | ||
219 | .description = "Sony Clie 5.0", | ||
346 | .id_table = clie_id_5_table, | 220 | .id_table = clie_id_5_table, |
347 | .num_interrupt_in = NUM_DONT_CARE, | 221 | .num_interrupt_in = NUM_DONT_CARE, |
348 | .num_bulk_in = 2, | 222 | .num_bulk_in = 2, |
@@ -367,10 +241,12 @@ static struct usb_serial_device_type clie_5_device = { | |||
367 | }; | 241 | }; |
368 | 242 | ||
369 | /* device info for the Sony Clie OS version 3.5 */ | 243 | /* device info for the Sony Clie OS version 3.5 */ |
370 | static struct usb_serial_device_type clie_3_5_device = { | 244 | static struct usb_serial_driver clie_3_5_device = { |
371 | .owner = THIS_MODULE, | 245 | .driver = { |
372 | .name = "Sony Clie 3.5", | 246 | .owner = THIS_MODULE, |
373 | .short_name = "clie_3.5", | 247 | .name = "clie_3.5", |
248 | }, | ||
249 | .description = "Sony Clie 3.5", | ||
374 | .id_table = clie_id_3_5_table, | 250 | .id_table = clie_id_3_5_table, |
375 | .num_interrupt_in = 0, | 251 | .num_interrupt_in = 0, |
376 | .num_bulk_in = 1, | 252 | .num_bulk_in = 1, |
@@ -782,7 +658,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i | |||
782 | break; | 658 | break; |
783 | } | 659 | } |
784 | dev_info(dev, "%s: port %d, is for %s use\n", | 660 | dev_info(dev, "%s: port %d, is for %s use\n", |
785 | serial->type->name, | 661 | serial->type->description, |
786 | connection_info->connections[i].port, string); | 662 | connection_info->connections[i].port, string); |
787 | } | 663 | } |
788 | } | 664 | } |
@@ -791,11 +667,11 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i | |||
791 | */ | 667 | */ |
792 | if (num_ports == 0 || num_ports > 2) { | 668 | if (num_ports == 0 || num_ports > 2) { |
793 | dev_warn (dev, "%s: No valid connect info available\n", | 669 | dev_warn (dev, "%s: No valid connect info available\n", |
794 | serial->type->name); | 670 | serial->type->description); |
795 | num_ports = 2; | 671 | num_ports = 2; |
796 | } | 672 | } |
797 | 673 | ||
798 | dev_info(dev, "%s: Number of ports: %d\n", serial->type->name, | 674 | dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, |
799 | num_ports); | 675 | num_ports); |
800 | 676 | ||
801 | /* | 677 | /* |
@@ -1125,7 +1001,7 @@ static int __init visor_init (void) | |||
1125 | retval = usb_register(&visor_driver); | 1001 | retval = usb_register(&visor_driver); |
1126 | if (retval) | 1002 | if (retval) |
1127 | goto failed_usb_register; | 1003 | goto failed_usb_register; |
1128 | info(DRIVER_DESC " " DRIVER_VERSION); | 1004 | info(DRIVER_DESC); |
1129 | 1005 | ||
1130 | return 0; | 1006 | return 0; |
1131 | failed_usb_register: | 1007 | failed_usb_register: |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index cf3bc30675a1..18c3183be769 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -156,10 +156,12 @@ static void whiteheat_unthrottle (struct usb_serial_port *port); | |||
156 | static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs); | 156 | static void whiteheat_read_callback (struct urb *urb, struct pt_regs *regs); |
157 | static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); | 157 | static void whiteheat_write_callback (struct urb *urb, struct pt_regs *regs); |
158 | 158 | ||
159 | static struct usb_serial_device_type whiteheat_fake_device = { | 159 | static struct usb_serial_driver whiteheat_fake_device = { |
160 | .owner = THIS_MODULE, | 160 | .driver = { |
161 | .name = "Connect Tech - WhiteHEAT - (prerenumeration)", | 161 | .owner = THIS_MODULE, |
162 | .short_name = "whiteheatnofirm", | 162 | .name = "whiteheatnofirm", |
163 | }, | ||
164 | .description = "Connect Tech - WhiteHEAT - (prerenumeration)", | ||
163 | .id_table = id_table_prerenumeration, | 165 | .id_table = id_table_prerenumeration, |
164 | .num_interrupt_in = NUM_DONT_CARE, | 166 | .num_interrupt_in = NUM_DONT_CARE, |
165 | .num_bulk_in = NUM_DONT_CARE, | 167 | .num_bulk_in = NUM_DONT_CARE, |
@@ -169,10 +171,12 @@ static struct usb_serial_device_type whiteheat_fake_device = { | |||
169 | .attach = whiteheat_firmware_attach, | 171 | .attach = whiteheat_firmware_attach, |
170 | }; | 172 | }; |
171 | 173 | ||
172 | static struct usb_serial_device_type whiteheat_device = { | 174 | static struct usb_serial_driver whiteheat_device = { |
173 | .owner = THIS_MODULE, | 175 | .driver = { |
174 | .name = "Connect Tech - WhiteHEAT", | 176 | .owner = THIS_MODULE, |
175 | .short_name = "whiteheat", | 177 | .name = "whiteheat", |
178 | }, | ||
179 | .description = "Connect Tech - WhiteHEAT", | ||
176 | .id_table = id_table_std, | 180 | .id_table = id_table_std, |
177 | .num_interrupt_in = NUM_DONT_CARE, | 181 | .num_interrupt_in = NUM_DONT_CARE, |
178 | .num_bulk_in = NUM_DONT_CARE, | 182 | .num_bulk_in = NUM_DONT_CARE, |
@@ -382,10 +386,10 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
382 | usb_clear_halt(serial->dev, pipe); | 386 | usb_clear_halt(serial->dev, pipe); |
383 | ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS); | 387 | ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS); |
384 | if (ret) { | 388 | if (ret) { |
385 | err("%s: Couldn't send command [%d]", serial->type->name, ret); | 389 | err("%s: Couldn't send command [%d]", serial->type->description, ret); |
386 | goto no_firmware; | 390 | goto no_firmware; |
387 | } else if (alen != sizeof(command)) { | 391 | } else if (alen != sizeof(command)) { |
388 | err("%s: Send command incomplete [%d]", serial->type->name, alen); | 392 | err("%s: Send command incomplete [%d]", serial->type->description, alen); |
389 | goto no_firmware; | 393 | goto no_firmware; |
390 | } | 394 | } |
391 | 395 | ||
@@ -394,19 +398,19 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
394 | usb_clear_halt(serial->dev, pipe); | 398 | usb_clear_halt(serial->dev, pipe); |
395 | ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); | 399 | ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS); |
396 | if (ret) { | 400 | if (ret) { |
397 | err("%s: Couldn't get results [%d]", serial->type->name, ret); | 401 | err("%s: Couldn't get results [%d]", serial->type->description, ret); |
398 | goto no_firmware; | 402 | goto no_firmware; |
399 | } else if (alen != sizeof(result)) { | 403 | } else if (alen != sizeof(result)) { |
400 | err("%s: Get results incomplete [%d]", serial->type->name, alen); | 404 | err("%s: Get results incomplete [%d]", serial->type->description, alen); |
401 | goto no_firmware; | 405 | goto no_firmware; |
402 | } else if (result[0] != command[0]) { | 406 | } else if (result[0] != command[0]) { |
403 | err("%s: Command failed [%d]", serial->type->name, result[0]); | 407 | err("%s: Command failed [%d]", serial->type->description, result[0]); |
404 | goto no_firmware; | 408 | goto no_firmware; |
405 | } | 409 | } |
406 | 410 | ||
407 | hw_info = (struct whiteheat_hw_info *)&result[1]; | 411 | hw_info = (struct whiteheat_hw_info *)&result[1]; |
408 | 412 | ||
409 | info("%s: Driver %s: Firmware v%d.%02d", serial->type->name, | 413 | info("%s: Driver %s: Firmware v%d.%02d", serial->type->description, |
410 | DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); | 414 | DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev); |
411 | 415 | ||
412 | for (i = 0; i < serial->num_ports; i++) { | 416 | for (i = 0; i < serial->num_ports; i++) { |
@@ -414,7 +418,7 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
414 | 418 | ||
415 | info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); | 419 | info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); |
416 | if (info == NULL) { | 420 | if (info == NULL) { |
417 | err("%s: Out of memory for port structures\n", serial->type->name); | 421 | err("%s: Out of memory for port structures\n", serial->type->description); |
418 | goto no_private; | 422 | goto no_private; |
419 | } | 423 | } |
420 | 424 | ||
@@ -484,7 +488,7 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
484 | 488 | ||
485 | command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); | 489 | command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); |
486 | if (command_info == NULL) { | 490 | if (command_info == NULL) { |
487 | err("%s: Out of memory for port structures\n", serial->type->name); | 491 | err("%s: Out of memory for port structures\n", serial->type->description); |
488 | goto no_command_private; | 492 | goto no_command_private; |
489 | } | 493 | } |
490 | 494 | ||
@@ -501,9 +505,9 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
501 | 505 | ||
502 | no_firmware: | 506 | no_firmware: |
503 | /* Firmware likely not running */ | 507 | /* Firmware likely not running */ |
504 | err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name); | 508 | err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description); |
505 | err("%s: If the firmware is not running (status led not blinking)\n", serial->type->name); | 509 | err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description); |
506 | err("%s: please contact support@connecttech.com\n", serial->type->name); | 510 | err("%s: please contact support@connecttech.com\n", serial->type->description); |
507 | return -ENODEV; | 511 | return -ENODEV; |
508 | 512 | ||
509 | no_command_private: | 513 | no_command_private: |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index bb9819cc8826..1a9679f76f5a 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -2,7 +2,8 @@ | |||
2 | # USB Storage driver configuration | 2 | # USB Storage driver configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information" | 5 | comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'" |
6 | comment "may also be needed; see USB_STORAGE Help for more information" | ||
6 | depends on USB | 7 | depends on USB |
7 | 8 | ||
8 | config USB_STORAGE | 9 | config USB_STORAGE |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 356342c6e7a2..33c55a6261bb 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Driver for SCM Microsystems USB-ATAPI cable | 1 | /* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable |
2 | * | 2 | * |
3 | * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ | 3 | * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ |
4 | * | 4 | * |
@@ -67,10 +67,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); | |||
67 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); | 67 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Convenience function to produce an ATAPI read/write sectors command | 70 | * Convenience function to produce an ATA read/write sectors command |
71 | * Use cmd=0x20 for read, cmd=0x30 for write | 71 | * Use cmd=0x20 for read, cmd=0x30 for write |
72 | */ | 72 | */ |
73 | static void usbat_pack_atapi_sector_cmd(unsigned char *buf, | 73 | static void usbat_pack_ata_sector_cmd(unsigned char *buf, |
74 | unsigned char thistime, | 74 | unsigned char thistime, |
75 | u32 sector, unsigned char cmd) | 75 | u32 sector, unsigned char cmd) |
76 | { | 76 | { |
@@ -196,10 +196,12 @@ static int usbat_check_status(struct us_data *us) | |||
196 | if (rc != USB_STOR_XFER_GOOD) | 196 | if (rc != USB_STOR_XFER_GOOD) |
197 | return USB_STOR_TRANSPORT_FAILED; | 197 | return USB_STOR_TRANSPORT_FAILED; |
198 | 198 | ||
199 | if (*reply & 0x01 && *reply != 0x51) // error/check condition (0x51 is ok) | 199 | /* error/check condition (0x51 is ok) */ |
200 | if (*reply & 0x01 && *reply != 0x51) | ||
200 | return USB_STOR_TRANSPORT_FAILED; | 201 | return USB_STOR_TRANSPORT_FAILED; |
201 | 202 | ||
202 | if (*reply & 0x20) // device fault | 203 | /* device fault */ |
204 | if (*reply & 0x20) | ||
203 | return USB_STOR_TRANSPORT_FAILED; | 205 | return USB_STOR_TRANSPORT_FAILED; |
204 | 206 | ||
205 | return USB_STOR_TRANSPORT_GOOD; | 207 | return USB_STOR_TRANSPORT_GOOD; |
@@ -222,29 +224,39 @@ static int usbat_set_shuttle_features(struct us_data *us, | |||
222 | command[0] = 0x40; | 224 | command[0] = 0x40; |
223 | command[1] = USBAT_CMD_SET_FEAT; | 225 | command[1] = USBAT_CMD_SET_FEAT; |
224 | 226 | ||
225 | // The only bit relevant to ATA access is bit 6 | 227 | /* |
226 | // which defines 8 bit data access (set) or 16 bit (unset) | 228 | * The only bit relevant to ATA access is bit 6 |
229 | * which defines 8 bit data access (set) or 16 bit (unset) | ||
230 | */ | ||
227 | command[2] = epp_control; | 231 | command[2] = epp_control; |
228 | 232 | ||
229 | // If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, | 233 | /* |
230 | // ET1 and ET2 define an external event to be checked for on event of a | 234 | * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, |
231 | // _read_blocks or _write_blocks operation. The read/write will not take | 235 | * ET1 and ET2 define an external event to be checked for on event of a |
232 | // place unless the defined trigger signal is active. | 236 | * _read_blocks or _write_blocks operation. The read/write will not take |
237 | * place unless the defined trigger signal is active. | ||
238 | */ | ||
233 | command[3] = external_trigger; | 239 | command[3] = external_trigger; |
234 | 240 | ||
235 | // The resultant byte of the mask operation (see mask_byte) is compared for | 241 | /* |
236 | // equivalence with this test pattern. If equal, the read/write will take | 242 | * The resultant byte of the mask operation (see mask_byte) is compared for |
237 | // place. | 243 | * equivalence with this test pattern. If equal, the read/write will take |
244 | * place. | ||
245 | */ | ||
238 | command[4] = test_pattern; | 246 | command[4] = test_pattern; |
239 | 247 | ||
240 | // This value is logically ANDed with the status register field specified | 248 | /* |
241 | // in the read/write command. | 249 | * This value is logically ANDed with the status register field specified |
250 | * in the read/write command. | ||
251 | */ | ||
242 | command[5] = mask_byte; | 252 | command[5] = mask_byte; |
243 | 253 | ||
244 | // If ALQ is set in the qualifier, this field contains the address of the | 254 | /* |
245 | // registers where the byte count should be read for transferring the data. | 255 | * If ALQ is set in the qualifier, this field contains the address of the |
246 | // If ALQ is not set, then this field contains the number of bytes to be | 256 | * registers where the byte count should be read for transferring the data. |
247 | // transferred. | 257 | * If ALQ is not set, then this field contains the number of bytes to be |
258 | * transferred. | ||
259 | */ | ||
248 | command[6] = subcountL; | 260 | command[6] = subcountL; |
249 | command[7] = subcountH; | 261 | command[7] = subcountH; |
250 | 262 | ||
@@ -273,26 +285,26 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) | |||
273 | 285 | ||
274 | if (result!=USB_STOR_XFER_GOOD) | 286 | if (result!=USB_STOR_XFER_GOOD) |
275 | return USB_STOR_TRANSPORT_ERROR; | 287 | return USB_STOR_TRANSPORT_ERROR; |
276 | if (*status & 0x01) { // check condition | 288 | if (*status & 0x01) { /* check condition */ |
277 | result = usbat_read(us, USBAT_ATA, 0x10, status); | 289 | result = usbat_read(us, USBAT_ATA, 0x10, status); |
278 | return USB_STOR_TRANSPORT_FAILED; | 290 | return USB_STOR_TRANSPORT_FAILED; |
279 | } | 291 | } |
280 | if (*status & 0x20) // device fault | 292 | if (*status & 0x20) /* device fault */ |
281 | return USB_STOR_TRANSPORT_FAILED; | 293 | return USB_STOR_TRANSPORT_FAILED; |
282 | 294 | ||
283 | if ((*status & 0x80)==0x00) { // not busy | 295 | if ((*status & 0x80)==0x00) { /* not busy */ |
284 | US_DEBUGP("Waited not busy for %d steps\n", i); | 296 | US_DEBUGP("Waited not busy for %d steps\n", i); |
285 | return USB_STOR_TRANSPORT_GOOD; | 297 | return USB_STOR_TRANSPORT_GOOD; |
286 | } | 298 | } |
287 | 299 | ||
288 | if (i<500) | 300 | if (i<500) |
289 | msleep(10); // 5 seconds | 301 | msleep(10); /* 5 seconds */ |
290 | else if (i<700) | 302 | else if (i<700) |
291 | msleep(50); // 10 seconds | 303 | msleep(50); /* 10 seconds */ |
292 | else if (i<1200) | 304 | else if (i<1200) |
293 | msleep(100); // 50 seconds | 305 | msleep(100); /* 50 seconds */ |
294 | else | 306 | else |
295 | msleep(1000); // X minutes | 307 | msleep(1000); /* X minutes */ |
296 | } | 308 | } |
297 | 309 | ||
298 | US_DEBUGP("Waited not busy for %d minutes, timing out.\n", | 310 | US_DEBUGP("Waited not busy for %d minutes, timing out.\n", |
@@ -412,9 +424,12 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, | |||
412 | 424 | ||
413 | if (i==0) { | 425 | if (i==0) { |
414 | cmdlen = 16; | 426 | cmdlen = 16; |
415 | // Write to multiple registers | 427 | /* |
416 | // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here, | 428 | * Write to multiple registers |
417 | // but that's what came out of the trace every single time. | 429 | * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is |
430 | * necessary here, but that's what came out of the | ||
431 | * trace every single time. | ||
432 | */ | ||
418 | command[0] = 0x40; | 433 | command[0] = 0x40; |
419 | command[1] = access | USBAT_CMD_WRITE_REGS; | 434 | command[1] = access | USBAT_CMD_WRITE_REGS; |
420 | command[2] = 0x07; | 435 | command[2] = 0x07; |
@@ -426,7 +441,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, | |||
426 | } else | 441 | } else |
427 | cmdlen = 8; | 442 | cmdlen = 8; |
428 | 443 | ||
429 | // Conditionally read or write blocks | 444 | /* Conditionally read or write blocks */ |
430 | command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); | 445 | command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); |
431 | command[cmdlen-7] = access | | 446 | command[cmdlen-7] = access | |
432 | (direction==DMA_TO_DEVICE ? | 447 | (direction==DMA_TO_DEVICE ? |
@@ -456,11 +471,6 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, | |||
456 | 471 | ||
457 | } | 472 | } |
458 | 473 | ||
459 | |||
460 | //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n", | ||
461 | // direction == DMA_TO_DEVICE ? "out" : "in", | ||
462 | // len, use_sg); | ||
463 | |||
464 | result = usb_stor_bulk_transfer_sg(us, | 474 | result = usb_stor_bulk_transfer_sg(us, |
465 | pipe, content, len, use_sg, NULL); | 475 | pipe, content, len, use_sg, NULL); |
466 | 476 | ||
@@ -508,9 +518,9 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, | |||
508 | 518 | ||
509 | if (result!=USB_STOR_XFER_GOOD) | 519 | if (result!=USB_STOR_XFER_GOOD) |
510 | return USB_STOR_TRANSPORT_ERROR; | 520 | return USB_STOR_TRANSPORT_ERROR; |
511 | if (*status & 0x01) // check condition | 521 | if (*status & 0x01) /* check condition */ |
512 | return USB_STOR_TRANSPORT_FAILED; | 522 | return USB_STOR_TRANSPORT_FAILED; |
513 | if (*status & 0x20) // device fault | 523 | if (*status & 0x20) /* device fault */ |
514 | return USB_STOR_TRANSPORT_FAILED; | 524 | return USB_STOR_TRANSPORT_FAILED; |
515 | 525 | ||
516 | US_DEBUGP("Redoing %s\n", | 526 | US_DEBUGP("Redoing %s\n", |
@@ -547,32 +557,32 @@ static int usbat_multiple_write(struct us_data *us, | |||
547 | 557 | ||
548 | BUG_ON(num_registers > US_IOBUF_SIZE/2); | 558 | BUG_ON(num_registers > US_IOBUF_SIZE/2); |
549 | 559 | ||
550 | // Write to multiple registers, ATA access | 560 | /* Write to multiple registers, ATA access */ |
551 | command[0] = 0x40; | 561 | command[0] = 0x40; |
552 | command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS; | 562 | command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS; |
553 | 563 | ||
554 | // No relevance | 564 | /* No relevance */ |
555 | command[2] = 0; | 565 | command[2] = 0; |
556 | command[3] = 0; | 566 | command[3] = 0; |
557 | command[4] = 0; | 567 | command[4] = 0; |
558 | command[5] = 0; | 568 | command[5] = 0; |
559 | 569 | ||
560 | // Number of bytes to be transferred (incl. addresses and data) | 570 | /* Number of bytes to be transferred (incl. addresses and data) */ |
561 | command[6] = LSB_of(num_registers*2); | 571 | command[6] = LSB_of(num_registers*2); |
562 | command[7] = MSB_of(num_registers*2); | 572 | command[7] = MSB_of(num_registers*2); |
563 | 573 | ||
564 | // The setup command | 574 | /* The setup command */ |
565 | result = usbat_execute_command(us, command, 8); | 575 | result = usbat_execute_command(us, command, 8); |
566 | if (result != USB_STOR_XFER_GOOD) | 576 | if (result != USB_STOR_XFER_GOOD) |
567 | return USB_STOR_TRANSPORT_ERROR; | 577 | return USB_STOR_TRANSPORT_ERROR; |
568 | 578 | ||
569 | // Create the reg/data, reg/data sequence | 579 | /* Create the reg/data, reg/data sequence */ |
570 | for (i=0; i<num_registers; i++) { | 580 | for (i=0; i<num_registers; i++) { |
571 | data[i<<1] = registers[i]; | 581 | data[i<<1] = registers[i]; |
572 | data[1+(i<<1)] = data_out[i]; | 582 | data[1+(i<<1)] = data_out[i]; |
573 | } | 583 | } |
574 | 584 | ||
575 | // Send the data | 585 | /* Send the data */ |
576 | result = usbat_bulk_write(us, data, num_registers*2); | 586 | result = usbat_bulk_write(us, data, num_registers*2); |
577 | if (result != USB_STOR_XFER_GOOD) | 587 | if (result != USB_STOR_XFER_GOOD) |
578 | return USB_STOR_TRANSPORT_ERROR; | 588 | return USB_STOR_TRANSPORT_ERROR; |
@@ -606,17 +616,17 @@ static int usbat_read_blocks(struct us_data *us, | |||
606 | command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK; | 616 | command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK; |
607 | command[2] = USBAT_ATA_DATA; | 617 | command[2] = USBAT_ATA_DATA; |
608 | command[3] = USBAT_ATA_STATUS; | 618 | command[3] = USBAT_ATA_STATUS; |
609 | command[4] = 0xFD; // Timeout (ms); | 619 | command[4] = 0xFD; /* Timeout (ms); */ |
610 | command[5] = USBAT_QUAL_FCQ; | 620 | command[5] = USBAT_QUAL_FCQ; |
611 | command[6] = LSB_of(len); | 621 | command[6] = LSB_of(len); |
612 | command[7] = MSB_of(len); | 622 | command[7] = MSB_of(len); |
613 | 623 | ||
614 | // Multiple block read setup command | 624 | /* Multiple block read setup command */ |
615 | result = usbat_execute_command(us, command, 8); | 625 | result = usbat_execute_command(us, command, 8); |
616 | if (result != USB_STOR_XFER_GOOD) | 626 | if (result != USB_STOR_XFER_GOOD) |
617 | return USB_STOR_TRANSPORT_FAILED; | 627 | return USB_STOR_TRANSPORT_FAILED; |
618 | 628 | ||
619 | // Read the blocks we just asked for | 629 | /* Read the blocks we just asked for */ |
620 | result = usbat_bulk_read(us, buffer, len); | 630 | result = usbat_bulk_read(us, buffer, len); |
621 | if (result != USB_STOR_XFER_GOOD) | 631 | if (result != USB_STOR_XFER_GOOD) |
622 | return USB_STOR_TRANSPORT_FAILED; | 632 | return USB_STOR_TRANSPORT_FAILED; |
@@ -647,17 +657,17 @@ static int usbat_write_blocks(struct us_data *us, | |||
647 | command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK; | 657 | command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK; |
648 | command[2] = USBAT_ATA_DATA; | 658 | command[2] = USBAT_ATA_DATA; |
649 | command[3] = USBAT_ATA_STATUS; | 659 | command[3] = USBAT_ATA_STATUS; |
650 | command[4] = 0xFD; // Timeout (ms) | 660 | command[4] = 0xFD; /* Timeout (ms) */ |
651 | command[5] = USBAT_QUAL_FCQ; | 661 | command[5] = USBAT_QUAL_FCQ; |
652 | command[6] = LSB_of(len); | 662 | command[6] = LSB_of(len); |
653 | command[7] = MSB_of(len); | 663 | command[7] = MSB_of(len); |
654 | 664 | ||
655 | // Multiple block write setup command | 665 | /* Multiple block write setup command */ |
656 | result = usbat_execute_command(us, command, 8); | 666 | result = usbat_execute_command(us, command, 8); |
657 | if (result != USB_STOR_XFER_GOOD) | 667 | if (result != USB_STOR_XFER_GOOD) |
658 | return USB_STOR_TRANSPORT_FAILED; | 668 | return USB_STOR_TRANSPORT_FAILED; |
659 | 669 | ||
660 | // Write the data | 670 | /* Write the data */ |
661 | result = usbat_bulk_write(us, buffer, len); | 671 | result = usbat_bulk_write(us, buffer, len); |
662 | if (result != USB_STOR_XFER_GOOD) | 672 | if (result != USB_STOR_XFER_GOOD) |
663 | return USB_STOR_TRANSPORT_FAILED; | 673 | return USB_STOR_TRANSPORT_FAILED; |
@@ -711,16 +721,20 @@ static int usbat_device_reset(struct us_data *us) | |||
711 | { | 721 | { |
712 | int rc; | 722 | int rc; |
713 | 723 | ||
714 | // Reset peripheral, enable peripheral control signals | 724 | /* |
715 | // (bring reset signal up) | 725 | * Reset peripheral, enable peripheral control signals |
726 | * (bring reset signal up) | ||
727 | */ | ||
716 | rc = usbat_write_user_io(us, | 728 | rc = usbat_write_user_io(us, |
717 | USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 729 | USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0, |
718 | USBAT_UIO_EPAD | USBAT_UIO_1); | 730 | USBAT_UIO_EPAD | USBAT_UIO_1); |
719 | if (rc != USB_STOR_XFER_GOOD) | 731 | if (rc != USB_STOR_XFER_GOOD) |
720 | return USB_STOR_TRANSPORT_ERROR; | 732 | return USB_STOR_TRANSPORT_ERROR; |
721 | 733 | ||
722 | // Enable peripheral control signals | 734 | /* |
723 | // (bring reset signal down) | 735 | * Enable peripheral control signals |
736 | * (bring reset signal down) | ||
737 | */ | ||
724 | rc = usbat_write_user_io(us, | 738 | rc = usbat_write_user_io(us, |
725 | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 739 | USBAT_UIO_OE1 | USBAT_UIO_OE0, |
726 | USBAT_UIO_EPAD | USBAT_UIO_1); | 740 | USBAT_UIO_EPAD | USBAT_UIO_1); |
@@ -737,7 +751,7 @@ static int usbat_device_enable_cdt(struct us_data *us) | |||
737 | { | 751 | { |
738 | int rc; | 752 | int rc; |
739 | 753 | ||
740 | // Enable peripheral control signals and card detect | 754 | /* Enable peripheral control signals and card detect */ |
741 | rc = usbat_write_user_io(us, | 755 | rc = usbat_write_user_io(us, |
742 | USBAT_UIO_ACKD | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 756 | USBAT_UIO_ACKD | USBAT_UIO_OE1 | USBAT_UIO_OE0, |
743 | USBAT_UIO_EPAD | USBAT_UIO_1); | 757 | USBAT_UIO_EPAD | USBAT_UIO_1); |
@@ -786,7 +800,7 @@ static int usbat_flash_check_media(struct us_data *us, | |||
786 | if (rc != USB_STOR_XFER_GOOD) | 800 | if (rc != USB_STOR_XFER_GOOD) |
787 | return USB_STOR_TRANSPORT_ERROR; | 801 | return USB_STOR_TRANSPORT_ERROR; |
788 | 802 | ||
789 | // Check for media existence | 803 | /* Check for media existence */ |
790 | rc = usbat_flash_check_media_present(uio); | 804 | rc = usbat_flash_check_media_present(uio); |
791 | if (rc == USBAT_FLASH_MEDIA_NONE) { | 805 | if (rc == USBAT_FLASH_MEDIA_NONE) { |
792 | info->sense_key = 0x02; | 806 | info->sense_key = 0x02; |
@@ -795,11 +809,11 @@ static int usbat_flash_check_media(struct us_data *us, | |||
795 | return USB_STOR_TRANSPORT_FAILED; | 809 | return USB_STOR_TRANSPORT_FAILED; |
796 | } | 810 | } |
797 | 811 | ||
798 | // Check for media change | 812 | /* Check for media change */ |
799 | rc = usbat_flash_check_media_changed(uio); | 813 | rc = usbat_flash_check_media_changed(uio); |
800 | if (rc == USBAT_FLASH_MEDIA_CHANGED) { | 814 | if (rc == USBAT_FLASH_MEDIA_CHANGED) { |
801 | 815 | ||
802 | // Reset and re-enable card detect | 816 | /* Reset and re-enable card detect */ |
803 | rc = usbat_device_reset(us); | 817 | rc = usbat_device_reset(us); |
804 | if (rc != USB_STOR_TRANSPORT_GOOD) | 818 | if (rc != USB_STOR_TRANSPORT_GOOD) |
805 | return rc; | 819 | return rc; |
@@ -855,15 +869,15 @@ static int usbat_identify_device(struct us_data *us, | |||
855 | if (rc != USB_STOR_XFER_GOOD) | 869 | if (rc != USB_STOR_XFER_GOOD) |
856 | return USB_STOR_TRANSPORT_ERROR; | 870 | return USB_STOR_TRANSPORT_ERROR; |
857 | 871 | ||
858 | // Check for error bit | 872 | /* Check for error bit, or if the command 'fell through' */ |
859 | if (status & 0x01) { | 873 | if (status == 0xA1 || !(status & 0x01)) { |
860 | // Device is a CompactFlash reader/writer | 874 | /* Device is HP 8200 */ |
861 | US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); | ||
862 | info->devicetype = USBAT_DEV_FLASH; | ||
863 | } else { | ||
864 | // Device is HP 8200 | ||
865 | US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); | 875 | US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); |
866 | info->devicetype = USBAT_DEV_HP8200; | 876 | info->devicetype = USBAT_DEV_HP8200; |
877 | } else { | ||
878 | /* Device is a CompactFlash reader/writer */ | ||
879 | US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); | ||
880 | info->devicetype = USBAT_DEV_FLASH; | ||
867 | } | 881 | } |
868 | 882 | ||
869 | return USB_STOR_TRANSPORT_GOOD; | 883 | return USB_STOR_TRANSPORT_GOOD; |
@@ -916,7 +930,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, | |||
916 | if (!reply) | 930 | if (!reply) |
917 | return USB_STOR_TRANSPORT_ERROR; | 931 | return USB_STOR_TRANSPORT_ERROR; |
918 | 932 | ||
919 | // ATAPI command : IDENTIFY DEVICE | 933 | /* ATA command : IDENTIFY DEVICE */ |
920 | rc = usbat_multiple_write(us, registers, command, 3); | 934 | rc = usbat_multiple_write(us, registers, command, 3); |
921 | if (rc != USB_STOR_XFER_GOOD) { | 935 | if (rc != USB_STOR_XFER_GOOD) { |
922 | US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n"); | 936 | US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n"); |
@@ -924,7 +938,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, | |||
924 | goto leave; | 938 | goto leave; |
925 | } | 939 | } |
926 | 940 | ||
927 | // Read device status | 941 | /* Read device status */ |
928 | if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) { | 942 | if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) { |
929 | rc = USB_STOR_TRANSPORT_ERROR; | 943 | rc = USB_STOR_TRANSPORT_ERROR; |
930 | goto leave; | 944 | goto leave; |
@@ -932,7 +946,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, | |||
932 | 946 | ||
933 | msleep(100); | 947 | msleep(100); |
934 | 948 | ||
935 | // Read the device identification data | 949 | /* Read the device identification data */ |
936 | rc = usbat_read_block(us, reply, 512); | 950 | rc = usbat_read_block(us, reply, 512); |
937 | if (rc != USB_STOR_TRANSPORT_GOOD) | 951 | if (rc != USB_STOR_TRANSPORT_GOOD) |
938 | goto leave; | 952 | goto leave; |
@@ -977,19 +991,23 @@ static int usbat_flash_read_data(struct us_data *us, | |||
977 | if (result != USB_STOR_TRANSPORT_GOOD) | 991 | if (result != USB_STOR_TRANSPORT_GOOD) |
978 | return result; | 992 | return result; |
979 | 993 | ||
980 | // we're working in LBA mode. according to the ATA spec, | 994 | /* |
981 | // we can support up to 28-bit addressing. I don't know if Jumpshot | 995 | * we're working in LBA mode. according to the ATA spec, |
982 | // supports beyond 24-bit addressing. It's kind of hard to test | 996 | * we can support up to 28-bit addressing. I don't know if Jumpshot |
983 | // since it requires > 8GB CF card. | 997 | * supports beyond 24-bit addressing. It's kind of hard to test |
998 | * since it requires > 8GB CF card. | ||
999 | */ | ||
984 | 1000 | ||
985 | if (sector > 0x0FFFFFFF) | 1001 | if (sector > 0x0FFFFFFF) |
986 | return USB_STOR_TRANSPORT_ERROR; | 1002 | return USB_STOR_TRANSPORT_ERROR; |
987 | 1003 | ||
988 | totallen = sectors * info->ssize; | 1004 | totallen = sectors * info->ssize; |
989 | 1005 | ||
990 | // Since we don't read more than 64 KB at a time, we have to create | 1006 | /* |
991 | // a bounce buffer and move the data a piece at a time between the | 1007 | * Since we don't read more than 64 KB at a time, we have to create |
992 | // bounce buffer and the actual transfer buffer. | 1008 | * a bounce buffer and move the data a piece at a time between the |
1009 | * bounce buffer and the actual transfer buffer. | ||
1010 | */ | ||
993 | 1011 | ||
994 | alloclen = min(totallen, 65536u); | 1012 | alloclen = min(totallen, 65536u); |
995 | buffer = kmalloc(alloclen, GFP_NOIO); | 1013 | buffer = kmalloc(alloclen, GFP_NOIO); |
@@ -997,27 +1015,29 @@ static int usbat_flash_read_data(struct us_data *us, | |||
997 | return USB_STOR_TRANSPORT_ERROR; | 1015 | return USB_STOR_TRANSPORT_ERROR; |
998 | 1016 | ||
999 | do { | 1017 | do { |
1000 | // loop, never allocate or transfer more than 64k at once | 1018 | /* |
1001 | // (min(128k, 255*info->ssize) is the real limit) | 1019 | * loop, never allocate or transfer more than 64k at once |
1020 | * (min(128k, 255*info->ssize) is the real limit) | ||
1021 | */ | ||
1002 | len = min(totallen, alloclen); | 1022 | len = min(totallen, alloclen); |
1003 | thistime = (len / info->ssize) & 0xff; | 1023 | thistime = (len / info->ssize) & 0xff; |
1004 | 1024 | ||
1005 | // ATAPI command 0x20 (READ SECTORS) | 1025 | /* ATA command 0x20 (READ SECTORS) */ |
1006 | usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x20); | 1026 | usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20); |
1007 | 1027 | ||
1008 | // Write/execute ATAPI read command | 1028 | /* Write/execute ATA read command */ |
1009 | result = usbat_multiple_write(us, registers, command, 7); | 1029 | result = usbat_multiple_write(us, registers, command, 7); |
1010 | if (result != USB_STOR_TRANSPORT_GOOD) | 1030 | if (result != USB_STOR_TRANSPORT_GOOD) |
1011 | goto leave; | 1031 | goto leave; |
1012 | 1032 | ||
1013 | // Read the data we just requested | 1033 | /* Read the data we just requested */ |
1014 | result = usbat_read_blocks(us, buffer, len); | 1034 | result = usbat_read_blocks(us, buffer, len); |
1015 | if (result != USB_STOR_TRANSPORT_GOOD) | 1035 | if (result != USB_STOR_TRANSPORT_GOOD) |
1016 | goto leave; | 1036 | goto leave; |
1017 | 1037 | ||
1018 | US_DEBUGP("usbat_flash_read_data: %d bytes\n", len); | 1038 | US_DEBUGP("usbat_flash_read_data: %d bytes\n", len); |
1019 | 1039 | ||
1020 | // Store the data in the transfer buffer | 1040 | /* Store the data in the transfer buffer */ |
1021 | usb_stor_access_xfer_buf(buffer, len, us->srb, | 1041 | usb_stor_access_xfer_buf(buffer, len, us->srb, |
1022 | &sg_idx, &sg_offset, TO_XFER_BUF); | 1042 | &sg_idx, &sg_offset, TO_XFER_BUF); |
1023 | 1043 | ||
@@ -1061,19 +1081,23 @@ static int usbat_flash_write_data(struct us_data *us, | |||
1061 | if (result != USB_STOR_TRANSPORT_GOOD) | 1081 | if (result != USB_STOR_TRANSPORT_GOOD) |
1062 | return result; | 1082 | return result; |
1063 | 1083 | ||
1064 | // we're working in LBA mode. according to the ATA spec, | 1084 | /* |
1065 | // we can support up to 28-bit addressing. I don't know if Jumpshot | 1085 | * we're working in LBA mode. according to the ATA spec, |
1066 | // supports beyond 24-bit addressing. It's kind of hard to test | 1086 | * we can support up to 28-bit addressing. I don't know if the device |
1067 | // since it requires > 8GB CF card. | 1087 | * supports beyond 24-bit addressing. It's kind of hard to test |
1088 | * since it requires > 8GB media. | ||
1089 | */ | ||
1068 | 1090 | ||
1069 | if (sector > 0x0FFFFFFF) | 1091 | if (sector > 0x0FFFFFFF) |
1070 | return USB_STOR_TRANSPORT_ERROR; | 1092 | return USB_STOR_TRANSPORT_ERROR; |
1071 | 1093 | ||
1072 | totallen = sectors * info->ssize; | 1094 | totallen = sectors * info->ssize; |
1073 | 1095 | ||
1074 | // Since we don't write more than 64 KB at a time, we have to create | 1096 | /* |
1075 | // a bounce buffer and move the data a piece at a time between the | 1097 | * Since we don't write more than 64 KB at a time, we have to create |
1076 | // bounce buffer and the actual transfer buffer. | 1098 | * a bounce buffer and move the data a piece at a time between the |
1099 | * bounce buffer and the actual transfer buffer. | ||
1100 | */ | ||
1077 | 1101 | ||
1078 | alloclen = min(totallen, 65536u); | 1102 | alloclen = min(totallen, 65536u); |
1079 | buffer = kmalloc(alloclen, GFP_NOIO); | 1103 | buffer = kmalloc(alloclen, GFP_NOIO); |
@@ -1081,24 +1105,26 @@ static int usbat_flash_write_data(struct us_data *us, | |||
1081 | return USB_STOR_TRANSPORT_ERROR; | 1105 | return USB_STOR_TRANSPORT_ERROR; |
1082 | 1106 | ||
1083 | do { | 1107 | do { |
1084 | // loop, never allocate or transfer more than 64k at once | 1108 | /* |
1085 | // (min(128k, 255*info->ssize) is the real limit) | 1109 | * loop, never allocate or transfer more than 64k at once |
1110 | * (min(128k, 255*info->ssize) is the real limit) | ||
1111 | */ | ||
1086 | len = min(totallen, alloclen); | 1112 | len = min(totallen, alloclen); |
1087 | thistime = (len / info->ssize) & 0xff; | 1113 | thistime = (len / info->ssize) & 0xff; |
1088 | 1114 | ||
1089 | // Get the data from the transfer buffer | 1115 | /* Get the data from the transfer buffer */ |
1090 | usb_stor_access_xfer_buf(buffer, len, us->srb, | 1116 | usb_stor_access_xfer_buf(buffer, len, us->srb, |
1091 | &sg_idx, &sg_offset, FROM_XFER_BUF); | 1117 | &sg_idx, &sg_offset, FROM_XFER_BUF); |
1092 | 1118 | ||
1093 | // ATAPI command 0x30 (WRITE SECTORS) | 1119 | /* ATA command 0x30 (WRITE SECTORS) */ |
1094 | usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x30); | 1120 | usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); |
1095 | 1121 | ||
1096 | // Write/execute ATAPI write command | 1122 | /* Write/execute ATA write command */ |
1097 | result = usbat_multiple_write(us, registers, command, 7); | 1123 | result = usbat_multiple_write(us, registers, command, 7); |
1098 | if (result != USB_STOR_TRANSPORT_GOOD) | 1124 | if (result != USB_STOR_TRANSPORT_GOOD) |
1099 | goto leave; | 1125 | goto leave; |
1100 | 1126 | ||
1101 | // Write the data | 1127 | /* Write the data */ |
1102 | result = usbat_write_blocks(us, buffer, len); | 1128 | result = usbat_write_blocks(us, buffer, len); |
1103 | if (result != USB_STOR_TRANSPORT_GOOD) | 1129 | if (result != USB_STOR_TRANSPORT_GOOD) |
1104 | goto leave; | 1130 | goto leave; |
@@ -1169,42 +1195,44 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, | |||
1169 | srb->transfersize); | 1195 | srb->transfersize); |
1170 | } | 1196 | } |
1171 | 1197 | ||
1172 | // Since we only read in one block at a time, we have to create | 1198 | /* |
1173 | // a bounce buffer and move the data a piece at a time between the | 1199 | * Since we only read in one block at a time, we have to create |
1174 | // bounce buffer and the actual transfer buffer. | 1200 | * a bounce buffer and move the data a piece at a time between the |
1201 | * bounce buffer and the actual transfer buffer. | ||
1202 | */ | ||
1175 | 1203 | ||
1176 | len = (65535/srb->transfersize) * srb->transfersize; | 1204 | len = (65535/srb->transfersize) * srb->transfersize; |
1177 | US_DEBUGP("Max read is %d bytes\n", len); | 1205 | US_DEBUGP("Max read is %d bytes\n", len); |
1178 | len = min(len, srb->request_bufflen); | 1206 | len = min(len, srb->request_bufflen); |
1179 | buffer = kmalloc(len, GFP_NOIO); | 1207 | buffer = kmalloc(len, GFP_NOIO); |
1180 | if (buffer == NULL) // bloody hell! | 1208 | if (buffer == NULL) /* bloody hell! */ |
1181 | return USB_STOR_TRANSPORT_FAILED; | 1209 | return USB_STOR_TRANSPORT_FAILED; |
1182 | sector = short_pack(data[7+3], data[7+2]); | 1210 | sector = short_pack(data[7+3], data[7+2]); |
1183 | sector <<= 16; | 1211 | sector <<= 16; |
1184 | sector |= short_pack(data[7+5], data[7+4]); | 1212 | sector |= short_pack(data[7+5], data[7+4]); |
1185 | transferred = 0; | 1213 | transferred = 0; |
1186 | 1214 | ||
1187 | sg_segment = 0; // for keeping track of where we are in | 1215 | sg_segment = 0; /* for keeping track of where we are in */ |
1188 | sg_offset = 0; // the scatter/gather list | 1216 | sg_offset = 0; /* the scatter/gather list */ |
1189 | 1217 | ||
1190 | while (transferred != srb->request_bufflen) { | 1218 | while (transferred != srb->request_bufflen) { |
1191 | 1219 | ||
1192 | if (len > srb->request_bufflen - transferred) | 1220 | if (len > srb->request_bufflen - transferred) |
1193 | len = srb->request_bufflen - transferred; | 1221 | len = srb->request_bufflen - transferred; |
1194 | 1222 | ||
1195 | data[3] = len&0xFF; // (cylL) = expected length (L) | 1223 | data[3] = len&0xFF; /* (cylL) = expected length (L) */ |
1196 | data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) | 1224 | data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ |
1197 | 1225 | ||
1198 | // Fix up the SCSI command sector and num sectors | 1226 | /* Fix up the SCSI command sector and num sectors */ |
1199 | 1227 | ||
1200 | data[7+2] = MSB_of(sector>>16); // SCSI command sector | 1228 | data[7+2] = MSB_of(sector>>16); /* SCSI command sector */ |
1201 | data[7+3] = LSB_of(sector>>16); | 1229 | data[7+3] = LSB_of(sector>>16); |
1202 | data[7+4] = MSB_of(sector&0xFFFF); | 1230 | data[7+4] = MSB_of(sector&0xFFFF); |
1203 | data[7+5] = LSB_of(sector&0xFFFF); | 1231 | data[7+5] = LSB_of(sector&0xFFFF); |
1204 | if (data[7+0] == GPCMD_READ_CD) | 1232 | if (data[7+0] == GPCMD_READ_CD) |
1205 | data[7+6] = 0; | 1233 | data[7+6] = 0; |
1206 | data[7+7] = MSB_of(len / srb->transfersize); // SCSI command | 1234 | data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */ |
1207 | data[7+8] = LSB_of(len / srb->transfersize); // num sectors | 1235 | data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */ |
1208 | 1236 | ||
1209 | result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, | 1237 | result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, |
1210 | registers, data, 19, | 1238 | registers, data, 19, |
@@ -1217,16 +1245,16 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, | |||
1217 | if (result != USB_STOR_TRANSPORT_GOOD) | 1245 | if (result != USB_STOR_TRANSPORT_GOOD) |
1218 | break; | 1246 | break; |
1219 | 1247 | ||
1220 | // Store the data in the transfer buffer | 1248 | /* Store the data in the transfer buffer */ |
1221 | usb_stor_access_xfer_buf(buffer, len, srb, | 1249 | usb_stor_access_xfer_buf(buffer, len, srb, |
1222 | &sg_segment, &sg_offset, TO_XFER_BUF); | 1250 | &sg_segment, &sg_offset, TO_XFER_BUF); |
1223 | 1251 | ||
1224 | // Update the amount transferred and the sector number | 1252 | /* Update the amount transferred and the sector number */ |
1225 | 1253 | ||
1226 | transferred += len; | 1254 | transferred += len; |
1227 | sector += len / srb->transfersize; | 1255 | sector += len / srb->transfersize; |
1228 | 1256 | ||
1229 | } // while transferred != srb->request_bufflen | 1257 | } /* while transferred != srb->request_bufflen */ |
1230 | 1258 | ||
1231 | kfree(buffer); | 1259 | kfree(buffer); |
1232 | return result; | 1260 | return result; |
@@ -1237,7 +1265,7 @@ static int usbat_select_and_test_registers(struct us_data *us) | |||
1237 | int selector; | 1265 | int selector; |
1238 | unsigned char *status = us->iobuf; | 1266 | unsigned char *status = us->iobuf; |
1239 | 1267 | ||
1240 | // try device = master, then device = slave. | 1268 | /* try device = master, then device = slave. */ |
1241 | for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { | 1269 | for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { |
1242 | if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != | 1270 | if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != |
1243 | USB_STOR_XFER_GOOD) | 1271 | USB_STOR_XFER_GOOD) |
@@ -1298,7 +1326,7 @@ int init_usbat(struct us_data *us) | |||
1298 | memset(us->extra, 0, sizeof(struct usbat_info)); | 1326 | memset(us->extra, 0, sizeof(struct usbat_info)); |
1299 | info = (struct usbat_info *) (us->extra); | 1327 | info = (struct usbat_info *) (us->extra); |
1300 | 1328 | ||
1301 | // Enable peripheral control signals | 1329 | /* Enable peripheral control signals */ |
1302 | rc = usbat_write_user_io(us, | 1330 | rc = usbat_write_user_io(us, |
1303 | USBAT_UIO_OE1 | USBAT_UIO_OE0, | 1331 | USBAT_UIO_OE1 | USBAT_UIO_OE0, |
1304 | USBAT_UIO_EPAD | USBAT_UIO_1); | 1332 | USBAT_UIO_EPAD | USBAT_UIO_1); |
@@ -1337,7 +1365,7 @@ int init_usbat(struct us_data *us) | |||
1337 | 1365 | ||
1338 | US_DEBUGP("INIT 5\n"); | 1366 | US_DEBUGP("INIT 5\n"); |
1339 | 1367 | ||
1340 | // Enable peripheral control signals and card detect | 1368 | /* Enable peripheral control signals and card detect */ |
1341 | rc = usbat_device_enable_cdt(us); | 1369 | rc = usbat_device_enable_cdt(us); |
1342 | if (rc != USB_STOR_TRANSPORT_GOOD) | 1370 | if (rc != USB_STOR_TRANSPORT_GOOD) |
1343 | return rc; | 1371 | return rc; |
@@ -1364,7 +1392,7 @@ int init_usbat(struct us_data *us) | |||
1364 | 1392 | ||
1365 | US_DEBUGP("INIT 9\n"); | 1393 | US_DEBUGP("INIT 9\n"); |
1366 | 1394 | ||
1367 | // At this point, we need to detect which device we are using | 1395 | /* At this point, we need to detect which device we are using */ |
1368 | if (usbat_set_transport(us, info)) | 1396 | if (usbat_set_transport(us, info)) |
1369 | return USB_STOR_TRANSPORT_ERROR; | 1397 | return USB_STOR_TRANSPORT_ERROR; |
1370 | 1398 | ||
@@ -1414,10 +1442,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1414 | data[0] = 0x00; | 1442 | data[0] = 0x00; |
1415 | data[1] = 0x00; | 1443 | data[1] = 0x00; |
1416 | data[2] = 0x00; | 1444 | data[2] = 0x00; |
1417 | data[3] = len&0xFF; // (cylL) = expected length (L) | 1445 | data[3] = len&0xFF; /* (cylL) = expected length (L) */ |
1418 | data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) | 1446 | data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ |
1419 | data[5] = 0xB0; // (device sel) = slave | 1447 | data[5] = 0xB0; /* (device sel) = slave */ |
1420 | data[6] = 0xA0; // (command) = ATA PACKET COMMAND | 1448 | data[6] = 0xA0; /* (command) = ATA PACKET COMMAND */ |
1421 | 1449 | ||
1422 | for (i=7; i<19; i++) { | 1450 | for (i=7; i<19; i++) { |
1423 | registers[i] = 0x10; | 1451 | registers[i] = 0x10; |
@@ -1466,13 +1494,15 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1466 | return result; | 1494 | return result; |
1467 | } | 1495 | } |
1468 | 1496 | ||
1469 | // Write the 12-byte command header. | 1497 | /* |
1470 | 1498 | * Write the 12-byte command header. | |
1471 | // If the command is BLANK then set the timer for 75 minutes. | 1499 | * |
1472 | // Otherwise set it for 10 minutes. | 1500 | * If the command is BLANK then set the timer for 75 minutes. |
1473 | 1501 | * Otherwise set it for 10 minutes. | |
1474 | // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW | 1502 | * |
1475 | // AT SPEED 4 IS UNRELIABLE!!! | 1503 | * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW |
1504 | * AT SPEED 4 IS UNRELIABLE!!! | ||
1505 | */ | ||
1476 | 1506 | ||
1477 | if ( (result = usbat_write_block(us, | 1507 | if ( (result = usbat_write_block(us, |
1478 | USBAT_ATA, srb->cmnd, 12, | 1508 | USBAT_ATA, srb->cmnd, 12, |
@@ -1481,19 +1511,18 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1481 | return result; | 1511 | return result; |
1482 | } | 1512 | } |
1483 | 1513 | ||
1484 | // If there is response data to be read in | 1514 | /* If there is response data to be read in then do it here. */ |
1485 | // then do it here. | ||
1486 | 1515 | ||
1487 | if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { | 1516 | if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { |
1488 | 1517 | ||
1489 | // How many bytes to read in? Check cylL register | 1518 | /* How many bytes to read in? Check cylL register */ |
1490 | 1519 | ||
1491 | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != | 1520 | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != |
1492 | USB_STOR_XFER_GOOD) { | 1521 | USB_STOR_XFER_GOOD) { |
1493 | return USB_STOR_TRANSPORT_ERROR; | 1522 | return USB_STOR_TRANSPORT_ERROR; |
1494 | } | 1523 | } |
1495 | 1524 | ||
1496 | if (len > 0xFF) { // need to read cylH also | 1525 | if (len > 0xFF) { /* need to read cylH also */ |
1497 | len = *status; | 1526 | len = *status; |
1498 | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != | 1527 | if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != |
1499 | USB_STOR_XFER_GOOD) { | 1528 | USB_STOR_XFER_GOOD) { |
@@ -1556,13 +1585,16 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1556 | if (rc != USB_STOR_TRANSPORT_GOOD) | 1585 | if (rc != USB_STOR_TRANSPORT_GOOD) |
1557 | return rc; | 1586 | return rc; |
1558 | 1587 | ||
1559 | info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec | 1588 | /* hard coded 512 byte sectors as per ATA spec */ |
1589 | info->ssize = 0x200; | ||
1560 | US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", | 1590 | US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", |
1561 | info->sectors, info->ssize); | 1591 | info->sectors, info->ssize); |
1562 | 1592 | ||
1563 | // build the reply | 1593 | /* |
1564 | // note: must return the sector number of the last sector, | 1594 | * build the reply |
1565 | // *not* the total number of sectors | 1595 | * note: must return the sector number of the last sector, |
1596 | * *not* the total number of sectors | ||
1597 | */ | ||
1566 | ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); | 1598 | ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); |
1567 | ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); | 1599 | ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); |
1568 | usb_stor_set_xfer_buf(ptr, 8, srb); | 1600 | usb_stor_set_xfer_buf(ptr, 8, srb); |
@@ -1586,7 +1618,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1586 | } | 1618 | } |
1587 | 1619 | ||
1588 | if (srb->cmnd[0] == READ_12) { | 1620 | if (srb->cmnd[0] == READ_12) { |
1589 | // I don't think we'll ever see a READ_12 but support it anyway... | 1621 | /* |
1622 | * I don't think we'll ever see a READ_12 but support it anyway | ||
1623 | */ | ||
1590 | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 1624 | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | |
1591 | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); | 1625 | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); |
1592 | 1626 | ||
@@ -1608,7 +1642,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1608 | } | 1642 | } |
1609 | 1643 | ||
1610 | if (srb->cmnd[0] == WRITE_12) { | 1644 | if (srb->cmnd[0] == WRITE_12) { |
1611 | // I don't think we'll ever see a WRITE_12 but support it anyway... | 1645 | /* |
1646 | * I don't think we'll ever see a WRITE_12 but support it anyway | ||
1647 | */ | ||
1612 | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | | 1648 | block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | |
1613 | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); | 1649 | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); |
1614 | 1650 | ||
@@ -1645,8 +1681,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1645 | } | 1681 | } |
1646 | 1682 | ||
1647 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | 1683 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { |
1648 | // sure. whatever. not like we can stop the user from popping | 1684 | /* |
1649 | // the media out of the device (no locking doors, etc) | 1685 | * sure. whatever. not like we can stop the user from popping |
1686 | * the media out of the device (no locking doors, etc) | ||
1687 | */ | ||
1650 | return USB_STOR_TRANSPORT_GOOD; | 1688 | return USB_STOR_TRANSPORT_GOOD; |
1651 | } | 1689 | } |
1652 | 1690 | ||
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h index 5b8e867e2ae5..25e7d8b340b8 100644 --- a/drivers/usb/storage/shuttle_usbat.h +++ b/drivers/usb/storage/shuttle_usbat.h | |||
@@ -55,8 +55,8 @@ | |||
55 | #define USBAT_UIO_WRITE 0 | 55 | #define USBAT_UIO_WRITE 0 |
56 | 56 | ||
57 | /* Qualifier bits */ | 57 | /* Qualifier bits */ |
58 | #define USBAT_QUAL_FCQ 0x20 // full compare | 58 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ |
59 | #define USBAT_QUAL_ALQ 0x10 // auto load subcount | 59 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ |
60 | 60 | ||
61 | /* USBAT Flash Media status types */ | 61 | /* USBAT Flash Media status types */ |
62 | #define USBAT_FLASH_MEDIA_NONE 0 | 62 | #define USBAT_FLASH_MEDIA_NONE 0 |
@@ -67,39 +67,39 @@ | |||
67 | #define USBAT_FLASH_MEDIA_CHANGED 1 | 67 | #define USBAT_FLASH_MEDIA_CHANGED 1 |
68 | 68 | ||
69 | /* USBAT ATA registers */ | 69 | /* USBAT ATA registers */ |
70 | #define USBAT_ATA_DATA 0x10 // read/write data (R/W) | 70 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ |
71 | #define USBAT_ATA_FEATURES 0x11 // set features (W) | 71 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ |
72 | #define USBAT_ATA_ERROR 0x11 // error (R) | 72 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ |
73 | #define USBAT_ATA_SECCNT 0x12 // sector count (R/W) | 73 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ |
74 | #define USBAT_ATA_SECNUM 0x13 // sector number (R/W) | 74 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ |
75 | #define USBAT_ATA_LBA_ME 0x14 // cylinder low (R/W) | 75 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ |
76 | #define USBAT_ATA_LBA_HI 0x15 // cylinder high (R/W) | 76 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ |
77 | #define USBAT_ATA_DEVICE 0x16 // head/device selection (R/W) | 77 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ |
78 | #define USBAT_ATA_STATUS 0x17 // device status (R) | 78 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ |
79 | #define USBAT_ATA_CMD 0x17 // device command (W) | 79 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ |
80 | #define USBAT_ATA_ALTSTATUS 0x0E // status (no clear IRQ) (R) | 80 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ |
81 | 81 | ||
82 | /* USBAT User I/O Data registers */ | 82 | /* USBAT User I/O Data registers */ |
83 | #define USBAT_UIO_EPAD 0x80 // Enable Peripheral Control Signals | 83 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ |
84 | #define USBAT_UIO_CDT 0x40 // Card Detect (Read Only) | 84 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ |
85 | // CDT = ACKD & !UI1 & !UI0 | 85 | /* CDT = ACKD & !UI1 & !UI0 */ |
86 | #define USBAT_UIO_1 0x20 // I/O 1 | 86 | #define USBAT_UIO_1 0x20 /* I/O 1 */ |
87 | #define USBAT_UIO_0 0x10 // I/O 0 | 87 | #define USBAT_UIO_0 0x10 /* I/O 0 */ |
88 | #define USBAT_UIO_EPP_ATA 0x08 // 1=EPP mode, 0=ATA mode | 88 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ |
89 | #define USBAT_UIO_UI1 0x04 // Input 1 | 89 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ |
90 | #define USBAT_UIO_UI0 0x02 // Input 0 | 90 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ |
91 | #define USBAT_UIO_INTR_ACK 0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP) | 91 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ |
92 | 92 | ||
93 | /* USBAT User I/O Enable registers */ | 93 | /* USBAT User I/O Enable registers */ |
94 | #define USBAT_UIO_DRVRST 0x80 // Reset Peripheral | 94 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ |
95 | #define USBAT_UIO_ACKD 0x40 // Enable Card Detect | 95 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ |
96 | #define USBAT_UIO_OE1 0x20 // I/O 1 set=output/clr=input | 96 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ |
97 | // If ACKD=1, set OE1 to 1 also. | 97 | /* If ACKD=1, set OE1 to 1 also. */ |
98 | #define USBAT_UIO_OE0 0x10 // I/O 0 set=output/clr=input | 98 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ |
99 | #define USBAT_UIO_ADPRST 0x01 // Reset SCM chip | 99 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ |
100 | 100 | ||
101 | /* USBAT Features */ | 101 | /* USBAT Features */ |
102 | #define USBAT_FEAT_ETEN 0x80 // External trigger enable | 102 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ |
103 | #define USBAT_FEAT_U1 0x08 | 103 | #define USBAT_FEAT_U1 0x08 |
104 | #define USBAT_FEAT_U0 0x04 | 104 | #define USBAT_FEAT_U0 0x04 |
105 | #define USBAT_FEAT_ET1 0x02 | 105 | #define USBAT_FEAT_ET1 0x02 |
@@ -112,12 +112,12 @@ struct usbat_info { | |||
112 | int devicetype; | 112 | int devicetype; |
113 | 113 | ||
114 | /* Used for Flash readers only */ | 114 | /* Used for Flash readers only */ |
115 | unsigned long sectors; // total sector count | 115 | unsigned long sectors; /* total sector count */ |
116 | unsigned long ssize; // sector size in bytes | 116 | unsigned long ssize; /* sector size in bytes */ |
117 | 117 | ||
118 | unsigned char sense_key; | 118 | unsigned char sense_key; |
119 | unsigned long sense_asc; // additional sense code | 119 | unsigned long sense_asc; /* additional sense code */ |
120 | unsigned long sense_ascq; // additional sense code qualifier | 120 | unsigned long sense_ascq; /* additional sense code qualifier */ |
121 | }; | 121 | }; |
122 | 122 | ||
123 | #endif | 123 | #endif |
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index c1ba5301ebfc..7ca896a342e3 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
636 | 636 | ||
637 | /* use the new buffer we have */ | 637 | /* use the new buffer we have */ |
638 | old_request_buffer = srb->request_buffer; | 638 | old_request_buffer = srb->request_buffer; |
639 | srb->request_buffer = srb->sense_buffer; | 639 | srb->request_buffer = us->sensebuf; |
640 | 640 | ||
641 | /* set the buffer length for transfer */ | 641 | /* set the buffer length for transfer */ |
642 | old_request_bufflen = srb->request_bufflen; | 642 | old_request_bufflen = srb->request_bufflen; |
643 | srb->request_bufflen = 18; | 643 | srb->request_bufflen = US_SENSE_SIZE; |
644 | 644 | ||
645 | /* set up for no scatter-gather use */ | 645 | /* set up for no scatter-gather use */ |
646 | old_sg = srb->use_sg; | 646 | old_sg = srb->use_sg; |
@@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
652 | temp_result = us->transport(us->srb, us); | 652 | temp_result = us->transport(us->srb, us); |
653 | 653 | ||
654 | /* let's clean up right away */ | 654 | /* let's clean up right away */ |
655 | memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE); | ||
655 | srb->resid = old_resid; | 656 | srb->resid = old_resid; |
656 | srb->request_buffer = old_request_buffer; | 657 | srb->request_buffer = old_request_buffer; |
657 | srb->request_bufflen = old_request_bufflen; | 658 | srb->request_bufflen = old_request_bufflen; |
@@ -923,6 +924,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us) | |||
923 | int result; | 924 | int result; |
924 | 925 | ||
925 | /* issue the command */ | 926 | /* issue the command */ |
927 | us->iobuf[0] = 0; | ||
926 | result = usb_stor_control_msg(us, us->recv_ctrl_pipe, | 928 | result = usb_stor_control_msg(us, us->recv_ctrl_pipe, |
927 | US_BULK_GET_MAX_LUN, | 929 | US_BULK_GET_MAX_LUN, |
928 | USB_DIR_IN | USB_TYPE_CLASS | | 930 | USB_DIR_IN | USB_TYPE_CLASS | |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 8d9e0663f8fe..0a362cc781ad 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
@@ -50,7 +50,7 @@ | |||
50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | 50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ |
51 | #define US_PR_BULK 0x50 /* bulk only */ | 51 | #define US_PR_BULK 0x50 /* bulk only */ |
52 | #ifdef CONFIG_USB_STORAGE_USBAT | 52 | #ifdef CONFIG_USB_STORAGE_USBAT |
53 | #define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ | 53 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ |
54 | #endif | 54 | #endif |
55 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 55 | #ifdef CONFIG_USB_STORAGE_SDDR09 |
56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | 56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b79dad1b598c..9e926a8f2116 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -71,12 +71,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, | |||
71 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, | 71 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, |
72 | "HP", | 72 | "HP", |
73 | "CD-Writer+ 8200e", | 73 | "CD-Writer+ 8200e", |
74 | US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), | 74 | US_SC_8070, US_PR_USBAT, init_usbat, 0), |
75 | 75 | ||
76 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | 76 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, |
77 | "HP", | 77 | "HP", |
78 | "CD-Writer+ CD-4e", | 78 | "CD-Writer+ CD-4e", |
79 | US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), | 79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | 82 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ |
@@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, | |||
106 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 106 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
107 | US_FL_FIX_INQUIRY ), | 107 | US_FL_FIX_INQUIRY ), |
108 | 108 | ||
109 | /* Reported by Stefan Werner <dustbln@gmx.de> */ | ||
110 | UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, | ||
111 | "TrekStor", | ||
112 | "i.Beat Joy 2.0", | ||
113 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
114 | US_FL_IGNORE_RESIDUE ), | ||
115 | |||
109 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ | 116 | /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ |
110 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, | 117 | UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, |
111 | "SMSC", | 118 | "SMSC", |
@@ -244,6 +251,13 @@ UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999, | |||
244 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 251 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
245 | US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), | 252 | US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), |
246 | 253 | ||
254 | /* Reported by Simeon Simeonov <simeonov_2000@yahoo.com> */ | ||
255 | UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999, | ||
256 | "LEICA", | ||
257 | "D-LUX Camera", | ||
258 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
259 | US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), | ||
260 | |||
247 | /* Most of the following entries were developed with the help of | 261 | /* Most of the following entries were developed with the help of |
248 | * Shuttle/SCM directly. | 262 | * Shuttle/SCM directly. |
249 | */ | 263 | */ |
@@ -333,9 +347,9 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, | |||
333 | 347 | ||
334 | #ifdef CONFIG_USB_STORAGE_USBAT | 348 | #ifdef CONFIG_USB_STORAGE_USBAT |
335 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | 349 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, |
336 | "SCM", | 350 | "Shuttle/SCM", |
337 | "SCM USBAT-02", | 351 | "USBAT-02", |
338 | US_SC_SCSI, US_PR_SCM_ATAPI, init_usbat, | 352 | US_SC_SCSI, US_PR_USBAT, init_usbat, |
339 | US_FL_SINGLE_LUN), | 353 | US_FL_SINGLE_LUN), |
340 | #endif | 354 | #endif |
341 | 355 | ||
@@ -598,6 +612,16 @@ UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, | |||
598 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 612 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
599 | US_FL_FIX_CAPACITY ), | 613 | US_FL_FIX_CAPACITY ), |
600 | 614 | ||
615 | /* | ||
616 | * Reported by Tyson Vinson <lornoss@gmail.com> | ||
617 | * This particular productId is the iPod Nano | ||
618 | */ | ||
619 | UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999, | ||
620 | "Apple", | ||
621 | "iPod", | ||
622 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
623 | US_FL_FIX_CAPACITY ), | ||
624 | |||
601 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | 625 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT |
602 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, | 626 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, |
603 | "Lexar", | 627 | "Lexar", |
@@ -702,6 +726,14 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, | |||
702 | US_SC_SCSI, US_PR_CB, NULL, | 726 | US_SC_SCSI, US_PR_CB, NULL, |
703 | US_FL_SINGLE_LUN ), | 727 | US_FL_SINGLE_LUN ), |
704 | 728 | ||
729 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
730 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
731 | "Sandisk", | ||
732 | "ImageMate SDDR-05b", | ||
733 | US_SC_SCSI, US_PR_USBAT, init_usbat, | ||
734 | US_FL_SINGLE_LUN ), | ||
735 | #endif | ||
736 | |||
705 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | 737 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, |
706 | "Sandisk", | 738 | "Sandisk", |
707 | "ImageMate SDDR-12", | 739 | "ImageMate SDDR-12", |
@@ -724,7 +756,7 @@ UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, | |||
724 | #endif | 756 | #endif |
725 | 757 | ||
726 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ | 758 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ |
727 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0406, 0x0406, | 759 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, |
728 | "Freecom Technologies", | 760 | "Freecom Technologies", |
729 | "FHD-Classic", | 761 | "FHD-Classic", |
730 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 762 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index f9a9bfa1aef5..3847ebed2aa4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
56 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
57 | #include <linux/kthread.h> | ||
57 | 58 | ||
58 | #include <scsi/scsi.h> | 59 | #include <scsi/scsi.h> |
59 | #include <scsi/scsi_cmnd.h> | 60 | #include <scsi/scsi_cmnd.h> |
@@ -111,11 +112,6 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
111 | static DECLARE_COMPLETION(threads_gone); | 112 | static DECLARE_COMPLETION(threads_gone); |
112 | 113 | ||
113 | 114 | ||
114 | static int storage_probe(struct usb_interface *iface, | ||
115 | const struct usb_device_id *id); | ||
116 | |||
117 | static void storage_disconnect(struct usb_interface *iface); | ||
118 | |||
119 | /* The entries in this table, except for final ones here | 115 | /* The entries in this table, except for final ones here |
120 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, |
121 | * line for line with the entries of us_unsuaul_dev_list[]. | 117 | * line for line with the entries of us_unsuaul_dev_list[]. |
@@ -233,13 +229,40 @@ static struct us_unusual_dev us_unusual_dev_list[] = { | |||
233 | { NULL } | 229 | { NULL } |
234 | }; | 230 | }; |
235 | 231 | ||
236 | static struct usb_driver usb_storage_driver = { | 232 | |
237 | .owner = THIS_MODULE, | 233 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
238 | .name = "usb-storage", | 234 | |
239 | .probe = storage_probe, | 235 | static int storage_suspend(struct usb_interface *iface, pm_message_t message) |
240 | .disconnect = storage_disconnect, | 236 | { |
241 | .id_table = storage_usb_ids, | 237 | struct us_data *us = usb_get_intfdata(iface); |
242 | }; | 238 | |
239 | /* Wait until no command is running */ | ||
240 | down(&us->dev_semaphore); | ||
241 | |||
242 | US_DEBUGP("%s\n", __FUNCTION__); | ||
243 | iface->dev.power.power_state.event = message.event; | ||
244 | |||
245 | /* When runtime PM is working, we'll set a flag to indicate | ||
246 | * whether we should autoresume when a SCSI request arrives. */ | ||
247 | |||
248 | up(&us->dev_semaphore); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int storage_resume(struct usb_interface *iface) | ||
253 | { | ||
254 | struct us_data *us = usb_get_intfdata(iface); | ||
255 | |||
256 | down(&us->dev_semaphore); | ||
257 | |||
258 | US_DEBUGP("%s\n", __FUNCTION__); | ||
259 | iface->dev.power.power_state.event = PM_EVENT_ON; | ||
260 | |||
261 | up(&us->dev_semaphore); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | #endif /* CONFIG_PM */ | ||
243 | 266 | ||
244 | /* | 267 | /* |
245 | * fill_inquiry_response takes an unsigned char array (which must | 268 | * fill_inquiry_response takes an unsigned char array (which must |
@@ -288,22 +311,7 @@ static int usb_stor_control_thread(void * __us) | |||
288 | struct us_data *us = (struct us_data *)__us; | 311 | struct us_data *us = (struct us_data *)__us; |
289 | struct Scsi_Host *host = us_to_host(us); | 312 | struct Scsi_Host *host = us_to_host(us); |
290 | 313 | ||
291 | lock_kernel(); | ||
292 | |||
293 | /* | ||
294 | * This thread doesn't need any user-level access, | ||
295 | * so get rid of all our resources. | ||
296 | */ | ||
297 | daemonize("usb-storage"); | ||
298 | current->flags |= PF_NOFREEZE; | 314 | current->flags |= PF_NOFREEZE; |
299 | unlock_kernel(); | ||
300 | |||
301 | /* acquire a reference to the host, so it won't be deallocated | ||
302 | * until we're ready to exit */ | ||
303 | scsi_host_get(host); | ||
304 | |||
305 | /* signal that we've started the thread */ | ||
306 | complete(&(us->notify)); | ||
307 | 315 | ||
308 | for(;;) { | 316 | for(;;) { |
309 | US_DEBUGP("*** thread sleeping.\n"); | 317 | US_DEBUGP("*** thread sleeping.\n"); |
@@ -467,6 +475,12 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
467 | US_DEBUGP("I/O buffer allocation failed\n"); | 475 | US_DEBUGP("I/O buffer allocation failed\n"); |
468 | return -ENOMEM; | 476 | return -ENOMEM; |
469 | } | 477 | } |
478 | |||
479 | us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL); | ||
480 | if (!us->sensebuf) { | ||
481 | US_DEBUGP("Sense buffer allocation failed\n"); | ||
482 | return -ENOMEM; | ||
483 | } | ||
470 | return 0; | 484 | return 0; |
471 | } | 485 | } |
472 | 486 | ||
@@ -555,8 +569,8 @@ static int get_transport(struct us_data *us) | |||
555 | break; | 569 | break; |
556 | 570 | ||
557 | #ifdef CONFIG_USB_STORAGE_USBAT | 571 | #ifdef CONFIG_USB_STORAGE_USBAT |
558 | case US_PR_SCM_ATAPI: | 572 | case US_PR_USBAT: |
559 | us->transport_name = "SCM/ATAPI"; | 573 | us->transport_name = "Shuttle USBAT"; |
560 | us->transport = usbat_transport; | 574 | us->transport = usbat_transport; |
561 | us->transport_reset = usb_stor_CB_reset; | 575 | us->transport_reset = usb_stor_CB_reset; |
562 | us->max_lun = 1; | 576 | us->max_lun = 1; |
@@ -740,6 +754,7 @@ static int get_pipes(struct us_data *us) | |||
740 | static int usb_stor_acquire_resources(struct us_data *us) | 754 | static int usb_stor_acquire_resources(struct us_data *us) |
741 | { | 755 | { |
742 | int p; | 756 | int p; |
757 | struct task_struct *th; | ||
743 | 758 | ||
744 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); | 759 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); |
745 | if (!us->current_urb) { | 760 | if (!us->current_urb) { |
@@ -747,38 +762,28 @@ static int usb_stor_acquire_resources(struct us_data *us) | |||
747 | return -ENOMEM; | 762 | return -ENOMEM; |
748 | } | 763 | } |
749 | 764 | ||
750 | /* Lock the device while we carry out the next two operations */ | ||
751 | down(&us->dev_semaphore); | ||
752 | |||
753 | /* For bulk-only devices, determine the max LUN value */ | ||
754 | if (us->protocol == US_PR_BULK) { | ||
755 | p = usb_stor_Bulk_max_lun(us); | ||
756 | if (p < 0) { | ||
757 | up(&us->dev_semaphore); | ||
758 | return p; | ||
759 | } | ||
760 | us->max_lun = p; | ||
761 | } | ||
762 | |||
763 | /* Just before we start our control thread, initialize | 765 | /* Just before we start our control thread, initialize |
764 | * the device if it needs initialization */ | 766 | * the device if it needs initialization */ |
765 | if (us->unusual_dev->initFunction) | 767 | if (us->unusual_dev->initFunction) { |
766 | us->unusual_dev->initFunction(us); | 768 | p = us->unusual_dev->initFunction(us); |
767 | 769 | if (p) | |
768 | up(&us->dev_semaphore); | 770 | return p; |
771 | } | ||
769 | 772 | ||
770 | /* Start up our control thread */ | 773 | /* Start up our control thread */ |
771 | p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); | 774 | th = kthread_create(usb_stor_control_thread, us, "usb-storage"); |
772 | if (p < 0) { | 775 | if (IS_ERR(th)) { |
773 | printk(KERN_WARNING USB_STORAGE | 776 | printk(KERN_WARNING USB_STORAGE |
774 | "Unable to start control thread\n"); | 777 | "Unable to start control thread\n"); |
775 | return p; | 778 | return PTR_ERR(th); |
776 | } | 779 | } |
777 | us->pid = p; | ||
778 | atomic_inc(&total_threads); | ||
779 | 780 | ||
780 | /* Wait for the thread to start */ | 781 | /* Take a reference to the host for the control thread and |
781 | wait_for_completion(&(us->notify)); | 782 | * count it among all the threads we have launched. Then |
783 | * start it up. */ | ||
784 | scsi_host_get(us_to_host(us)); | ||
785 | atomic_inc(&total_threads); | ||
786 | wake_up_process(th); | ||
782 | 787 | ||
783 | return 0; | 788 | return 0; |
784 | } | 789 | } |
@@ -812,6 +817,8 @@ static void dissociate_dev(struct us_data *us) | |||
812 | { | 817 | { |
813 | US_DEBUGP("-- %s\n", __FUNCTION__); | 818 | US_DEBUGP("-- %s\n", __FUNCTION__); |
814 | 819 | ||
820 | kfree(us->sensebuf); | ||
821 | |||
815 | /* Free the device-related DMA-mapped buffers */ | 822 | /* Free the device-related DMA-mapped buffers */ |
816 | if (us->cr) | 823 | if (us->cr) |
817 | usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, | 824 | usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, |
@@ -872,21 +879,6 @@ static int usb_stor_scan_thread(void * __us) | |||
872 | { | 879 | { |
873 | struct us_data *us = (struct us_data *)__us; | 880 | struct us_data *us = (struct us_data *)__us; |
874 | 881 | ||
875 | /* | ||
876 | * This thread doesn't need any user-level access, | ||
877 | * so get rid of all our resources. | ||
878 | */ | ||
879 | lock_kernel(); | ||
880 | daemonize("usb-stor-scan"); | ||
881 | unlock_kernel(); | ||
882 | |||
883 | /* Acquire a reference to the host, so it won't be deallocated | ||
884 | * until we're ready to exit */ | ||
885 | scsi_host_get(us_to_host(us)); | ||
886 | |||
887 | /* Signal that we've started the thread */ | ||
888 | complete(&(us->notify)); | ||
889 | |||
890 | printk(KERN_DEBUG | 882 | printk(KERN_DEBUG |
891 | "usb-storage: device found at %d\n", us->pusb_dev->devnum); | 883 | "usb-storage: device found at %d\n", us->pusb_dev->devnum); |
892 | 884 | ||
@@ -904,6 +896,14 @@ retry: | |||
904 | 896 | ||
905 | /* If the device is still connected, perform the scanning */ | 897 | /* If the device is still connected, perform the scanning */ |
906 | if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { | 898 | if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { |
899 | |||
900 | /* For bulk-only devices, determine the max LUN value */ | ||
901 | if (us->protocol == US_PR_BULK && | ||
902 | !(us->flags & US_FL_SINGLE_LUN)) { | ||
903 | down(&us->dev_semaphore); | ||
904 | us->max_lun = usb_stor_Bulk_max_lun(us); | ||
905 | up(&us->dev_semaphore); | ||
906 | } | ||
907 | scsi_scan_host(us_to_host(us)); | 907 | scsi_scan_host(us_to_host(us)); |
908 | printk(KERN_DEBUG "usb-storage: device scan complete\n"); | 908 | printk(KERN_DEBUG "usb-storage: device scan complete\n"); |
909 | 909 | ||
@@ -923,6 +923,7 @@ static int storage_probe(struct usb_interface *intf, | |||
923 | struct us_data *us; | 923 | struct us_data *us; |
924 | const int id_index = id - storage_usb_ids; | 924 | const int id_index = id - storage_usb_ids; |
925 | int result; | 925 | int result; |
926 | struct task_struct *th; | ||
926 | 927 | ||
927 | US_DEBUGP("USB Mass Storage device detected\n"); | 928 | US_DEBUGP("USB Mass Storage device detected\n"); |
928 | 929 | ||
@@ -1003,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf, | |||
1003 | } | 1004 | } |
1004 | 1005 | ||
1005 | /* Start up the thread for delayed SCSI-device scanning */ | 1006 | /* Start up the thread for delayed SCSI-device scanning */ |
1006 | result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); | 1007 | th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); |
1007 | if (result < 0) { | 1008 | if (IS_ERR(th)) { |
1008 | printk(KERN_WARNING USB_STORAGE | 1009 | printk(KERN_WARNING USB_STORAGE |
1009 | "Unable to start the device-scanning thread\n"); | 1010 | "Unable to start the device-scanning thread\n"); |
1010 | quiesce_and_remove_host(us); | 1011 | quiesce_and_remove_host(us); |
1012 | result = PTR_ERR(th); | ||
1011 | goto BadDevice; | 1013 | goto BadDevice; |
1012 | } | 1014 | } |
1013 | atomic_inc(&total_threads); | ||
1014 | 1015 | ||
1015 | /* Wait for the thread to start */ | 1016 | /* Take a reference to the host for the scanning thread and |
1016 | wait_for_completion(&(us->notify)); | 1017 | * count it among all the threads we have launched. Then |
1018 | * start it up. */ | ||
1019 | scsi_host_get(us_to_host(us)); | ||
1020 | atomic_inc(&total_threads); | ||
1021 | wake_up_process(th); | ||
1017 | 1022 | ||
1018 | return 0; | 1023 | return 0; |
1019 | 1024 | ||
@@ -1038,6 +1043,18 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1038 | * Initialization and registration | 1043 | * Initialization and registration |
1039 | ***********************************************************************/ | 1044 | ***********************************************************************/ |
1040 | 1045 | ||
1046 | static struct usb_driver usb_storage_driver = { | ||
1047 | .owner = THIS_MODULE, | ||
1048 | .name = "usb-storage", | ||
1049 | .probe = storage_probe, | ||
1050 | .disconnect = storage_disconnect, | ||
1051 | #ifdef CONFIG_PM | ||
1052 | .suspend = storage_suspend, | ||
1053 | .resume = storage_resume, | ||
1054 | #endif | ||
1055 | .id_table = storage_usb_ids, | ||
1056 | }; | ||
1057 | |||
1041 | static int __init usb_stor_init(void) | 1058 | static int __init usb_stor_init(void) |
1042 | { | 1059 | { |
1043 | int retval; | 1060 | int retval; |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index a195adae57b6..98b09711a739 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS }; | |||
117 | */ | 117 | */ |
118 | 118 | ||
119 | #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ | 119 | #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ |
120 | #define US_SENSE_SIZE 18 /* Size of the autosense data buffer */ | ||
120 | 121 | ||
121 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 122 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); |
122 | typedef int (*trans_reset)(struct us_data*); | 123 | typedef int (*trans_reset)(struct us_data*); |
@@ -160,14 +161,12 @@ struct us_data { | |||
160 | struct scsi_cmnd *srb; /* current srb */ | 161 | struct scsi_cmnd *srb; /* current srb */ |
161 | unsigned int tag; /* current dCBWTag */ | 162 | unsigned int tag; /* current dCBWTag */ |
162 | 163 | ||
163 | /* thread information */ | ||
164 | int pid; /* control thread */ | ||
165 | |||
166 | /* control and bulk communications data */ | 164 | /* control and bulk communications data */ |
167 | struct urb *current_urb; /* USB requests */ | 165 | struct urb *current_urb; /* USB requests */ |
168 | struct usb_ctrlrequest *cr; /* control requests */ | 166 | struct usb_ctrlrequest *cr; /* control requests */ |
169 | struct usb_sg_request current_sg; /* scatter-gather req. */ | 167 | struct usb_sg_request current_sg; /* scatter-gather req. */ |
170 | unsigned char *iobuf; /* I/O buffer */ | 168 | unsigned char *iobuf; /* I/O buffer */ |
169 | unsigned char *sensebuf; /* sense data buffer */ | ||
171 | dma_addr_t cr_dma; /* buffer DMA addresses */ | 170 | dma_addr_t cr_dma; /* buffer DMA addresses */ |
172 | dma_addr_t iobuf_dma; | 171 | dma_addr_t iobuf_dma; |
173 | 172 | ||
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 353f24d45bc1..6c3a53f8f26c 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -223,9 +223,8 @@ static struct file_operations skel_fops = { | |||
223 | * and to have the device registered with devfs and the driver core | 223 | * and to have the device registered with devfs and the driver core |
224 | */ | 224 | */ |
225 | static struct usb_class_driver skel_class = { | 225 | static struct usb_class_driver skel_class = { |
226 | .name = "usb/skel%d", | 226 | .name = "skel%d", |
227 | .fops = &skel_fops, | 227 | .fops = &skel_fops, |
228 | .mode = S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, | ||
229 | .minor_base = USB_SKEL_MINOR_BASE, | 228 | .minor_base = USB_SKEL_MINOR_BASE, |
230 | }; | 229 | }; |
231 | 230 | ||