diff options
48 files changed, 578 insertions, 2383 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 3f1045993474..5b15d9d8896b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm) | |||
| 387 | struct acm_ru *rcv; | 387 | struct acm_ru *rcv; |
| 388 | unsigned long flags; | 388 | unsigned long flags; |
| 389 | unsigned char throttled; | 389 | unsigned char throttled; |
| 390 | struct usb_host_endpoint *ep; | ||
| 390 | 391 | ||
| 391 | dbg("Entering acm_rx_tasklet"); | 392 | dbg("Entering acm_rx_tasklet"); |
| 392 | 393 | ||
| @@ -462,11 +463,20 @@ urbs: | |||
| 462 | 463 | ||
| 463 | rcv->buffer = buf; | 464 | rcv->buffer = buf; |
| 464 | 465 | ||
| 465 | usb_fill_bulk_urb(rcv->urb, acm->dev, | 466 | ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out) |
| 466 | acm->rx_endpoint, | 467 | [usb_pipeendpoint(acm->rx_endpoint)]; |
| 467 | buf->base, | 468 | if (usb_endpoint_xfer_int(&ep->desc)) |
| 468 | acm->readsize, | 469 | usb_fill_int_urb(rcv->urb, acm->dev, |
| 469 | acm_read_bulk, rcv); | 470 | acm->rx_endpoint, |
| 471 | buf->base, | ||
| 472 | acm->readsize, | ||
| 473 | acm_read_bulk, rcv, ep->desc.bInterval); | ||
| 474 | else | ||
| 475 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
| 476 | acm->rx_endpoint, | ||
| 477 | buf->base, | ||
| 478 | acm->readsize, | ||
| 479 | acm_read_bulk, rcv); | ||
| 470 | rcv->urb->transfer_dma = buf->dma; | 480 | rcv->urb->transfer_dma = buf->dma; |
| 471 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 481 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 472 | 482 | ||
| @@ -1227,9 +1237,14 @@ made_compressed_probe: | |||
| 1227 | goto alloc_fail7; | 1237 | goto alloc_fail7; |
| 1228 | } | 1238 | } |
| 1229 | 1239 | ||
| 1230 | usb_fill_bulk_urb(snd->urb, usb_dev, | 1240 | if (usb_endpoint_xfer_int(epwrite)) |
| 1231 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 1241 | usb_fill_int_urb(snd->urb, usb_dev, |
| 1232 | NULL, acm->writesize, acm_write_bulk, snd); | 1242 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
| 1243 | NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); | ||
| 1244 | else | ||
| 1245 | usb_fill_bulk_urb(snd->urb, usb_dev, | ||
| 1246 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | ||
| 1247 | NULL, acm->writesize, acm_write_bulk, snd); | ||
| 1233 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1248 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
| 1234 | snd->instance = acm; | 1249 | snd->instance = acm; |
| 1235 | } | 1250 | } |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 3703789d0d2a..b09a527f7341 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
| @@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
| 751 | { | 751 | { |
| 752 | struct device *dev = &data->usb_dev->dev; | 752 | struct device *dev = &data->usb_dev->dev; |
| 753 | char *buffer; | 753 | char *buffer; |
| 754 | int rv; | 754 | int rv = 0; |
| 755 | 755 | ||
| 756 | buffer = kmalloc(0x18, GFP_KERNEL); | 756 | buffer = kmalloc(0x18, GFP_KERNEL); |
| 757 | if (!buffer) | 757 | if (!buffer) |
| @@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
| 763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); | 763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); |
| 764 | if (rv < 0) { | 764 | if (rv < 0) { |
| 765 | dev_err(dev, "usb_control_msg returned %d\n", rv); | 765 | dev_err(dev, "usb_control_msg returned %d\n", rv); |
| 766 | return rv; | 766 | goto err_out; |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
| @@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
| 773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); | 773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); |
| 774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { | 774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { |
| 775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
| 776 | return -EPERM; | 776 | rv = -EPERM; |
| 777 | goto err_out; | ||
| 777 | } | 778 | } |
| 778 | 779 | ||
| 779 | data->capabilities.interface_capabilities = buffer[4]; | 780 | data->capabilities.interface_capabilities = buffer[4]; |
| @@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
| 781 | data->capabilities.usb488_interface_capabilities = buffer[14]; | 782 | data->capabilities.usb488_interface_capabilities = buffer[14]; |
| 782 | data->capabilities.usb488_device_capabilities = buffer[15]; | 783 | data->capabilities.usb488_device_capabilities = buffer[15]; |
| 783 | 784 | ||
| 785 | err_out: | ||
| 784 | kfree(buffer); | 786 | kfree(buffer); |
| 785 | return 0; | 787 | return rv; |
| 786 | } | 788 | } |
| 787 | 789 | ||
| 788 | #define capability_attribute(name) \ | 790 | #define capability_attribute(name) \ |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 69280c35b5cb..ad925946f869 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
| @@ -28,7 +28,7 @@ comment "Miscellaneous USB options" | |||
| 28 | depends on USB | 28 | depends on USB |
| 29 | 29 | ||
| 30 | config USB_DEVICEFS | 30 | config USB_DEVICEFS |
| 31 | bool "USB device filesystem (DEPRECATED)" if EMBEDDED | 31 | bool "USB device filesystem (DEPRECATED)" |
| 32 | depends on USB | 32 | depends on USB |
| 33 | ---help--- | 33 | ---help--- |
| 34 | If you say Y here (and to "/proc file system support" in the "File | 34 | If you say Y here (and to "/proc file system support" in the "File |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 73c108d117b4..96f11715cd26 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
| @@ -136,17 +136,19 @@ static const struct class_info clas_info[] = | |||
| 136 | {USB_CLASS_AUDIO, "audio"}, | 136 | {USB_CLASS_AUDIO, "audio"}, |
| 137 | {USB_CLASS_COMM, "comm."}, | 137 | {USB_CLASS_COMM, "comm."}, |
| 138 | {USB_CLASS_HID, "HID"}, | 138 | {USB_CLASS_HID, "HID"}, |
| 139 | {USB_CLASS_HUB, "hub"}, | ||
| 140 | {USB_CLASS_PHYSICAL, "PID"}, | 139 | {USB_CLASS_PHYSICAL, "PID"}, |
| 140 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
| 141 | {USB_CLASS_PRINTER, "print"}, | 141 | {USB_CLASS_PRINTER, "print"}, |
| 142 | {USB_CLASS_MASS_STORAGE, "stor."}, | 142 | {USB_CLASS_MASS_STORAGE, "stor."}, |
| 143 | {USB_CLASS_HUB, "hub"}, | ||
| 143 | {USB_CLASS_CDC_DATA, "data"}, | 144 | {USB_CLASS_CDC_DATA, "data"}, |
| 144 | {USB_CLASS_APP_SPEC, "app."}, | ||
| 145 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
| 146 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
| 147 | {USB_CLASS_CSCID, "scard"}, | 145 | {USB_CLASS_CSCID, "scard"}, |
| 148 | {USB_CLASS_CONTENT_SEC, "c-sec"}, | 146 | {USB_CLASS_CONTENT_SEC, "c-sec"}, |
| 149 | {USB_CLASS_VIDEO, "video"}, | 147 | {USB_CLASS_VIDEO, "video"}, |
| 148 | {USB_CLASS_WIRELESS_CONTROLLER, "wlcon"}, | ||
| 149 | {USB_CLASS_MISC, "misc"}, | ||
| 150 | {USB_CLASS_APP_SPEC, "app."}, | ||
| 151 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
| 150 | {-1, "unk."} /* leave as last */ | 152 | {-1, "unk."} /* leave as last */ |
| 151 | }; | 153 | }; |
| 152 | 154 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 308609039c73..38b8bce782d6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -325,21 +325,34 @@ static void async_completed(struct urb *urb) | |||
| 325 | struct async *as = urb->context; | 325 | struct async *as = urb->context; |
| 326 | struct dev_state *ps = as->ps; | 326 | struct dev_state *ps = as->ps; |
| 327 | struct siginfo sinfo; | 327 | struct siginfo sinfo; |
| 328 | struct pid *pid = NULL; | ||
| 329 | uid_t uid = 0; | ||
| 330 | uid_t euid = 0; | ||
| 331 | u32 secid = 0; | ||
| 332 | int signr; | ||
| 328 | 333 | ||
| 329 | spin_lock(&ps->lock); | 334 | spin_lock(&ps->lock); |
| 330 | list_move_tail(&as->asynclist, &ps->async_completed); | 335 | list_move_tail(&as->asynclist, &ps->async_completed); |
| 331 | spin_unlock(&ps->lock); | ||
| 332 | as->status = urb->status; | 336 | as->status = urb->status; |
| 333 | if (as->signr) { | 337 | signr = as->signr; |
| 338 | if (signr) { | ||
| 334 | sinfo.si_signo = as->signr; | 339 | sinfo.si_signo = as->signr; |
| 335 | sinfo.si_errno = as->status; | 340 | sinfo.si_errno = as->status; |
| 336 | sinfo.si_code = SI_ASYNCIO; | 341 | sinfo.si_code = SI_ASYNCIO; |
| 337 | sinfo.si_addr = as->userurb; | 342 | sinfo.si_addr = as->userurb; |
| 338 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 343 | pid = as->pid; |
| 339 | as->euid, as->secid); | 344 | uid = as->uid; |
| 345 | euid = as->euid; | ||
| 346 | secid = as->secid; | ||
| 340 | } | 347 | } |
| 341 | snoop(&urb->dev->dev, "urb complete\n"); | 348 | snoop(&urb->dev->dev, "urb complete\n"); |
| 342 | snoop_urb(urb, as->userurb); | 349 | snoop_urb(urb, as->userurb); |
| 350 | spin_unlock(&ps->lock); | ||
| 351 | |||
| 352 | if (signr) | ||
| 353 | kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, | ||
| 354 | euid, secid); | ||
| 355 | |||
| 343 | wake_up(&ps->wait); | 356 | wake_up(&ps->wait); |
| 344 | } | 357 | } |
| 345 | 358 | ||
| @@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 982 | USBDEVFS_URB_ZERO_PACKET | | 995 | USBDEVFS_URB_ZERO_PACKET | |
| 983 | USBDEVFS_URB_NO_INTERRUPT)) | 996 | USBDEVFS_URB_NO_INTERRUPT)) |
| 984 | return -EINVAL; | 997 | return -EINVAL; |
| 985 | if (!uurb->buffer) | 998 | if (uurb->buffer_length > 0 && !uurb->buffer) |
| 986 | return -EINVAL; | 999 | return -EINVAL; |
| 987 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && | 1000 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && |
| 988 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { | 1001 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { |
| @@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1038 | is_in = 0; | 1051 | is_in = 0; |
| 1039 | uurb->endpoint &= ~USB_DIR_IN; | 1052 | uurb->endpoint &= ~USB_DIR_IN; |
| 1040 | } | 1053 | } |
| 1041 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
| 1042 | uurb->buffer, uurb->buffer_length)) { | ||
| 1043 | kfree(dr); | ||
| 1044 | return -EFAULT; | ||
| 1045 | } | ||
| 1046 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | 1054 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
| 1047 | "bRrequestType=%02x wValue=%04x " | 1055 | "bRrequestType=%02x wValue=%04x " |
| 1048 | "wIndex=%04x wLength=%04x\n", | 1056 | "wIndex=%04x wLength=%04x\n", |
| @@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1062 | uurb->number_of_packets = 0; | 1070 | uurb->number_of_packets = 0; |
| 1063 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1071 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
| 1064 | return -EINVAL; | 1072 | return -EINVAL; |
| 1065 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
| 1066 | uurb->buffer, uurb->buffer_length)) | ||
| 1067 | return -EFAULT; | ||
| 1068 | snoop(&ps->dev->dev, "bulk urb\n"); | 1073 | snoop(&ps->dev->dev, "bulk urb\n"); |
| 1069 | break; | 1074 | break; |
| 1070 | 1075 | ||
| @@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1106 | return -EINVAL; | 1111 | return -EINVAL; |
| 1107 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1112 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
| 1108 | return -EINVAL; | 1113 | return -EINVAL; |
| 1109 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
| 1110 | uurb->buffer, uurb->buffer_length)) | ||
| 1111 | return -EFAULT; | ||
| 1112 | snoop(&ps->dev->dev, "interrupt urb\n"); | 1114 | snoop(&ps->dev->dev, "interrupt urb\n"); |
| 1113 | break; | 1115 | break; |
| 1114 | 1116 | ||
| 1115 | default: | 1117 | default: |
| 1116 | return -EINVAL; | 1118 | return -EINVAL; |
| 1117 | } | 1119 | } |
| 1118 | as = alloc_async(uurb->number_of_packets); | 1120 | if (uurb->buffer_length > 0 && |
| 1119 | if (!as) { | 1121 | !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
| 1122 | uurb->buffer, uurb->buffer_length)) { | ||
| 1120 | kfree(isopkt); | 1123 | kfree(isopkt); |
| 1121 | kfree(dr); | 1124 | kfree(dr); |
| 1122 | return -ENOMEM; | 1125 | return -EFAULT; |
| 1123 | } | 1126 | } |
| 1124 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); | 1127 | as = alloc_async(uurb->number_of_packets); |
| 1125 | if (!as->urb->transfer_buffer) { | 1128 | if (!as) { |
| 1126 | kfree(isopkt); | 1129 | kfree(isopkt); |
| 1127 | kfree(dr); | 1130 | kfree(dr); |
| 1128 | free_async(as); | ||
| 1129 | return -ENOMEM; | 1131 | return -ENOMEM; |
| 1130 | } | 1132 | } |
| 1133 | if (uurb->buffer_length > 0) { | ||
| 1134 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, | ||
| 1135 | GFP_KERNEL); | ||
| 1136 | if (!as->urb->transfer_buffer) { | ||
| 1137 | kfree(isopkt); | ||
| 1138 | kfree(dr); | ||
| 1139 | free_async(as); | ||
| 1140 | return -ENOMEM; | ||
| 1141 | } | ||
| 1142 | } | ||
| 1131 | as->urb->dev = ps->dev; | 1143 | as->urb->dev = ps->dev; |
| 1132 | as->urb->pipe = (uurb->type << 30) | | 1144 | as->urb->pipe = (uurb->type << 30) | |
| 1133 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | | 1145 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
| @@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1169 | kfree(isopkt); | 1181 | kfree(isopkt); |
| 1170 | as->ps = ps; | 1182 | as->ps = ps; |
| 1171 | as->userurb = arg; | 1183 | as->userurb = arg; |
| 1172 | if (uurb->endpoint & USB_DIR_IN) | 1184 | if (is_in && uurb->buffer_length > 0) |
| 1173 | as->userbuffer = uurb->buffer; | 1185 | as->userbuffer = uurb->buffer; |
| 1174 | else | 1186 | else |
| 1175 | as->userbuffer = NULL; | 1187 | as->userbuffer = NULL; |
| @@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
| 1179 | as->uid = cred->uid; | 1191 | as->uid = cred->uid; |
| 1180 | as->euid = cred->euid; | 1192 | as->euid = cred->euid; |
| 1181 | security_task_getsecid(current, &as->secid); | 1193 | security_task_getsecid(current, &as->secid); |
| 1182 | if (!is_in) { | 1194 | if (!is_in && uurb->buffer_length > 0) { |
| 1183 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, | 1195 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
| 1184 | as->urb->transfer_buffer_length)) { | 1196 | uurb->buffer_length)) { |
| 1185 | free_async(as); | 1197 | free_async(as); |
| 1186 | return -EFAULT; | 1198 | return -EFAULT; |
| 1187 | } | 1199 | } |
| @@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
| 1231 | if (as->userbuffer) | 1243 | if (as->userbuffer) |
| 1232 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1244 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
| 1233 | urb->transfer_buffer_length)) | 1245 | urb->transfer_buffer_length)) |
| 1234 | return -EFAULT; | 1246 | goto err_out; |
| 1235 | if (put_user(as->status, &userurb->status)) | 1247 | if (put_user(as->status, &userurb->status)) |
| 1236 | return -EFAULT; | 1248 | goto err_out; |
| 1237 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1249 | if (put_user(urb->actual_length, &userurb->actual_length)) |
| 1238 | return -EFAULT; | 1250 | goto err_out; |
| 1239 | if (put_user(urb->error_count, &userurb->error_count)) | 1251 | if (put_user(urb->error_count, &userurb->error_count)) |
| 1240 | return -EFAULT; | 1252 | goto err_out; |
| 1241 | 1253 | ||
| 1242 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { | 1254 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
| 1243 | for (i = 0; i < urb->number_of_packets; i++) { | 1255 | for (i = 0; i < urb->number_of_packets; i++) { |
| 1244 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1256 | if (put_user(urb->iso_frame_desc[i].actual_length, |
| 1245 | &userurb->iso_frame_desc[i].actual_length)) | 1257 | &userurb->iso_frame_desc[i].actual_length)) |
| 1246 | return -EFAULT; | 1258 | goto err_out; |
| 1247 | if (put_user(urb->iso_frame_desc[i].status, | 1259 | if (put_user(urb->iso_frame_desc[i].status, |
| 1248 | &userurb->iso_frame_desc[i].status)) | 1260 | &userurb->iso_frame_desc[i].status)) |
| 1249 | return -EFAULT; | 1261 | goto err_out; |
| 1250 | } | 1262 | } |
| 1251 | } | 1263 | } |
| 1252 | 1264 | ||
| @@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
| 1255 | if (put_user(addr, (void __user * __user *)arg)) | 1267 | if (put_user(addr, (void __user * __user *)arg)) |
| 1256 | return -EFAULT; | 1268 | return -EFAULT; |
| 1257 | return 0; | 1269 | return 0; |
| 1270 | |||
| 1271 | err_out: | ||
| 1272 | free_async(as); | ||
| 1273 | return -EFAULT; | ||
| 1258 | } | 1274 | } |
| 1259 | 1275 | ||
| 1260 | static struct async *reap_as(struct dev_state *ps) | 1276 | static struct async *reap_as(struct dev_state *ps) |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index d397ecfd5b17..ec5c67ea07b7 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
| @@ -227,6 +227,10 @@ struct hc_driver { | |||
| 227 | /* has a port been handed over to a companion? */ | 227 | /* has a port been handed over to a companion? */ |
| 228 | int (*port_handed_over)(struct usb_hcd *, int); | 228 | int (*port_handed_over)(struct usb_hcd *, int); |
| 229 | 229 | ||
| 230 | /* CLEAR_TT_BUFFER completion callback */ | ||
| 231 | void (*clear_tt_buffer_complete)(struct usb_hcd *, | ||
| 232 | struct usb_host_endpoint *); | ||
| 233 | |||
| 230 | /* xHCI specific functions */ | 234 | /* xHCI specific functions */ |
| 231 | /* Called by usb_alloc_dev to alloc HC device structures */ | 235 | /* Called by usb_alloc_dev to alloc HC device structures */ |
| 232 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | 236 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2af3b4f06054..71f86c60d83c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | |||
| 450 | * talking to TTs must queue control transfers (not just bulk and iso), so | 450 | * talking to TTs must queue control transfers (not just bulk and iso), so |
| 451 | * both can talk to the same hub concurrently. | 451 | * both can talk to the same hub concurrently. |
| 452 | */ | 452 | */ |
| 453 | static void hub_tt_kevent (struct work_struct *work) | 453 | static void hub_tt_work(struct work_struct *work) |
| 454 | { | 454 | { |
| 455 | struct usb_hub *hub = | 455 | struct usb_hub *hub = |
| 456 | container_of(work, struct usb_hub, tt.kevent); | 456 | container_of(work, struct usb_hub, tt.clear_work); |
| 457 | unsigned long flags; | 457 | unsigned long flags; |
| 458 | int limit = 100; | 458 | int limit = 100; |
| 459 | 459 | ||
| @@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work) | |||
| 462 | struct list_head *next; | 462 | struct list_head *next; |
| 463 | struct usb_tt_clear *clear; | 463 | struct usb_tt_clear *clear; |
| 464 | struct usb_device *hdev = hub->hdev; | 464 | struct usb_device *hdev = hub->hdev; |
| 465 | const struct hc_driver *drv; | ||
| 465 | int status; | 466 | int status; |
| 466 | 467 | ||
| 467 | next = hub->tt.clear_list.next; | 468 | next = hub->tt.clear_list.next; |
| @@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work) | |||
| 471 | /* drop lock so HCD can concurrently report other TT errors */ | 472 | /* drop lock so HCD can concurrently report other TT errors */ |
| 472 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 473 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
| 473 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); | 474 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); |
| 474 | spin_lock_irqsave (&hub->tt.lock, flags); | ||
| 475 | |||
| 476 | if (status) | 475 | if (status) |
| 477 | dev_err (&hdev->dev, | 476 | dev_err (&hdev->dev, |
| 478 | "clear tt %d (%04x) error %d\n", | 477 | "clear tt %d (%04x) error %d\n", |
| 479 | clear->tt, clear->devinfo, status); | 478 | clear->tt, clear->devinfo, status); |
| 479 | |||
| 480 | /* Tell the HCD, even if the operation failed */ | ||
| 481 | drv = clear->hcd->driver; | ||
| 482 | if (drv->clear_tt_buffer_complete) | ||
| 483 | (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep); | ||
| 484 | |||
| 480 | kfree(clear); | 485 | kfree(clear); |
| 486 | spin_lock_irqsave(&hub->tt.lock, flags); | ||
| 481 | } | 487 | } |
| 482 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 488 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
| 483 | } | 489 | } |
| 484 | 490 | ||
| 485 | /** | 491 | /** |
| 486 | * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub | 492 | * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub |
| 487 | * @udev: the device whose split transaction failed | 493 | * @urb: an URB associated with the failed or incomplete split transaction |
| 488 | * @pipe: identifies the endpoint of the failed transaction | ||
| 489 | * | 494 | * |
| 490 | * High speed HCDs use this to tell the hub driver that some split control or | 495 | * High speed HCDs use this to tell the hub driver that some split control or |
| 491 | * bulk transaction failed in a way that requires clearing internal state of | 496 | * bulk transaction failed in a way that requires clearing internal state of |
| @@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work) | |||
| 495 | * It may not be possible for that hub to handle additional full (or low) | 500 | * It may not be possible for that hub to handle additional full (or low) |
| 496 | * speed transactions until that state is fully cleared out. | 501 | * speed transactions until that state is fully cleared out. |
| 497 | */ | 502 | */ |
| 498 | void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | 503 | int usb_hub_clear_tt_buffer(struct urb *urb) |
| 499 | { | 504 | { |
| 505 | struct usb_device *udev = urb->dev; | ||
| 506 | int pipe = urb->pipe; | ||
| 500 | struct usb_tt *tt = udev->tt; | 507 | struct usb_tt *tt = udev->tt; |
| 501 | unsigned long flags; | 508 | unsigned long flags; |
| 502 | struct usb_tt_clear *clear; | 509 | struct usb_tt_clear *clear; |
| @@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
| 508 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { | 515 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { |
| 509 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); | 516 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); |
| 510 | /* FIXME recover somehow ... RESET_TT? */ | 517 | /* FIXME recover somehow ... RESET_TT? */ |
| 511 | return; | 518 | return -ENOMEM; |
| 512 | } | 519 | } |
| 513 | 520 | ||
| 514 | /* info that CLEAR_TT_BUFFER needs */ | 521 | /* info that CLEAR_TT_BUFFER needs */ |
| @@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
| 520 | : (USB_ENDPOINT_XFER_BULK << 11); | 527 | : (USB_ENDPOINT_XFER_BULK << 11); |
| 521 | if (usb_pipein (pipe)) | 528 | if (usb_pipein (pipe)) |
| 522 | clear->devinfo |= 1 << 15; | 529 | clear->devinfo |= 1 << 15; |
| 523 | 530 | ||
| 531 | /* info for completion callback */ | ||
| 532 | clear->hcd = bus_to_hcd(udev->bus); | ||
| 533 | clear->ep = urb->ep; | ||
| 534 | |||
| 524 | /* tell keventd to clear state for this TT */ | 535 | /* tell keventd to clear state for this TT */ |
| 525 | spin_lock_irqsave (&tt->lock, flags); | 536 | spin_lock_irqsave (&tt->lock, flags); |
| 526 | list_add_tail (&clear->clear_list, &tt->clear_list); | 537 | list_add_tail (&clear->clear_list, &tt->clear_list); |
| 527 | schedule_work (&tt->kevent); | 538 | schedule_work(&tt->clear_work); |
| 528 | spin_unlock_irqrestore (&tt->lock, flags); | 539 | spin_unlock_irqrestore (&tt->lock, flags); |
| 540 | return 0; | ||
| 529 | } | 541 | } |
| 530 | EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); | 542 | EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer); |
| 531 | 543 | ||
| 532 | /* If do_delay is false, return the number of milliseconds the caller | 544 | /* If do_delay is false, return the number of milliseconds the caller |
| 533 | * needs to delay. | 545 | * needs to delay. |
| @@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
| 818 | if (hub->has_indicators) | 830 | if (hub->has_indicators) |
| 819 | cancel_delayed_work_sync(&hub->leds); | 831 | cancel_delayed_work_sync(&hub->leds); |
| 820 | if (hub->tt.hub) | 832 | if (hub->tt.hub) |
| 821 | cancel_work_sync(&hub->tt.kevent); | 833 | cancel_work_sync(&hub->tt.clear_work); |
| 822 | } | 834 | } |
| 823 | 835 | ||
| 824 | /* caller has locked the hub device */ | 836 | /* caller has locked the hub device */ |
| @@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub, | |||
| 935 | 947 | ||
| 936 | spin_lock_init (&hub->tt.lock); | 948 | spin_lock_init (&hub->tt.lock); |
| 937 | INIT_LIST_HEAD (&hub->tt.clear_list); | 949 | INIT_LIST_HEAD (&hub->tt.clear_list); |
| 938 | INIT_WORK (&hub->tt.kevent, hub_tt_kevent); | 950 | INIT_WORK(&hub->tt.clear_work, hub_tt_work); |
| 939 | switch (hdev->descriptor.bDeviceProtocol) { | 951 | switch (hdev->descriptor.bDeviceProtocol) { |
| 940 | case 0: | 952 | case 0: |
| 941 | break; | 953 | break; |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 889c0f32a40b..de8081f065ed 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
| @@ -188,16 +188,18 @@ struct usb_tt { | |||
| 188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ | 188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ |
| 189 | spinlock_t lock; | 189 | spinlock_t lock; |
| 190 | struct list_head clear_list; /* of usb_tt_clear */ | 190 | struct list_head clear_list; /* of usb_tt_clear */ |
| 191 | struct work_struct kevent; | 191 | struct work_struct clear_work; |
| 192 | }; | 192 | }; |
| 193 | 193 | ||
| 194 | struct usb_tt_clear { | 194 | struct usb_tt_clear { |
| 195 | struct list_head clear_list; | 195 | struct list_head clear_list; |
| 196 | unsigned tt; | 196 | unsigned tt; |
| 197 | u16 devinfo; | 197 | u16 devinfo; |
| 198 | struct usb_hcd *hcd; | ||
| 199 | struct usb_host_endpoint *ep; | ||
| 198 | }; | 200 | }; |
| 199 | 201 | ||
| 200 | extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); | 202 | extern int usb_hub_clear_tt_buffer(struct urb *urb); |
| 201 | extern void usb_ep0_reinit(struct usb_device *); | 203 | extern void usb_ep0_reinit(struct usb_device *); |
| 202 | 204 | ||
| 203 | #endif /* __LINUX_HUB_H */ | 205 | #endif /* __LINUX_HUB_H */ |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2bed83caacb1..9720e699f472 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, | |||
| 806 | return rc; | 806 | return rc; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf) | ||
| 810 | { | ||
| 811 | int err; | ||
| 812 | |||
| 813 | if (dev->have_langid) | ||
| 814 | return 0; | ||
| 815 | |||
| 816 | if (dev->string_langid < 0) | ||
| 817 | return -EPIPE; | ||
| 818 | |||
| 819 | err = usb_string_sub(dev, 0, 0, tbuf); | ||
| 820 | |||
| 821 | /* If the string was reported but is malformed, default to english | ||
| 822 | * (0x0409) */ | ||
| 823 | if (err == -ENODATA || (err > 0 && err < 4)) { | ||
| 824 | dev->string_langid = 0x0409; | ||
| 825 | dev->have_langid = 1; | ||
| 826 | dev_err(&dev->dev, | ||
| 827 | "string descriptor 0 malformed (err = %d), " | ||
| 828 | "defaulting to 0x%04x\n", | ||
| 829 | err, dev->string_langid); | ||
| 830 | return 0; | ||
| 831 | } | ||
| 832 | |||
| 833 | /* In case of all other errors, we assume the device is not able to | ||
| 834 | * deal with strings at all. Set string_langid to -1 in order to | ||
| 835 | * prevent any string to be retrieved from the device */ | ||
| 836 | if (err < 0) { | ||
| 837 | dev_err(&dev->dev, "string descriptor 0 read error: %d\n", | ||
| 838 | err); | ||
| 839 | dev->string_langid = -1; | ||
| 840 | return -EPIPE; | ||
| 841 | } | ||
| 842 | |||
| 843 | /* always use the first langid listed */ | ||
| 844 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
| 845 | dev->have_langid = 1; | ||
| 846 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
| 847 | dev->string_langid); | ||
| 848 | return 0; | ||
| 849 | } | ||
| 850 | |||
| 809 | /** | 851 | /** |
| 810 | * usb_string - returns UTF-8 version of a string descriptor | 852 | * usb_string - returns UTF-8 version of a string descriptor |
| 811 | * @dev: the device whose string descriptor is being retrieved | 853 | * @dev: the device whose string descriptor is being retrieved |
| @@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
| 837 | if (!tbuf) | 879 | if (!tbuf) |
| 838 | return -ENOMEM; | 880 | return -ENOMEM; |
| 839 | 881 | ||
| 840 | /* get langid for strings if it's not yet known */ | 882 | err = usb_get_langid(dev, tbuf); |
| 841 | if (!dev->have_langid) { | 883 | if (err < 0) |
| 842 | err = usb_string_sub(dev, 0, 0, tbuf); | 884 | goto errout; |
| 843 | if (err < 0) { | ||
| 844 | dev_err(&dev->dev, | ||
| 845 | "string descriptor 0 read error: %d\n", | ||
| 846 | err); | ||
| 847 | } else if (err < 4) { | ||
| 848 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | ||
| 849 | } else { | ||
| 850 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
| 851 | /* always use the first langid listed */ | ||
| 852 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
| 853 | dev->string_langid); | ||
| 854 | } | ||
| 855 | |||
| 856 | dev->have_langid = 1; | ||
| 857 | } | ||
| 858 | 885 | ||
| 859 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 886 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
| 860 | if (err < 0) | 887 | if (err < 0) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5d1ddf485d1e..7f8e83a954ac 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -286,6 +286,27 @@ config USB_S3C_HSOTG | |||
| 286 | default USB_GADGET | 286 | default USB_GADGET |
| 287 | select USB_GADGET_SELECTED | 287 | select USB_GADGET_SELECTED |
| 288 | 288 | ||
| 289 | config USB_GADGET_IMX | ||
| 290 | boolean "Freescale IMX USB Peripheral Controller" | ||
| 291 | depends on ARCH_MX1 | ||
| 292 | help | ||
| 293 | Freescale's IMX series include an integrated full speed | ||
| 294 | USB 1.1 device controller. The controller in the IMX series | ||
| 295 | is register-compatible. | ||
| 296 | |||
| 297 | It has Six fixed-function endpoints, as well as endpoint | ||
| 298 | zero (for control transfers). | ||
| 299 | |||
| 300 | Say "y" to link the driver statically, or "m" to build a | ||
| 301 | dynamically linked module called "imx_udc" and force all | ||
| 302 | gadget drivers to also be dynamically linked. | ||
| 303 | |||
| 304 | config USB_IMX | ||
| 305 | tristate | ||
| 306 | depends on USB_GADGET_IMX | ||
| 307 | default USB_GADGET | ||
| 308 | select USB_GADGET_SELECTED | ||
| 309 | |||
| 289 | config USB_GADGET_S3C2410 | 310 | config USB_GADGET_S3C2410 |
| 290 | boolean "S3C2410 USB Device Controller" | 311 | boolean "S3C2410 USB Device Controller" |
| 291 | depends on ARCH_S3C2410 | 312 | depends on ARCH_S3C2410 |
| @@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC | |||
| 321 | This OTG-capable silicon IP is used in dual designs including | 342 | This OTG-capable silicon IP is used in dual designs including |
| 322 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin | 343 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin |
| 323 | 344 | ||
| 324 | config USB_GADGET_IMX | ||
| 325 | boolean "Freescale IMX USB Peripheral Controller" | ||
| 326 | depends on ARCH_MX1 | ||
| 327 | help | ||
| 328 | Freescale's IMX series include an integrated full speed | ||
| 329 | USB 1.1 device controller. The controller in the IMX series | ||
| 330 | is register-compatible. | ||
| 331 | |||
| 332 | It has Six fixed-function endpoints, as well as endpoint | ||
| 333 | zero (for control transfers). | ||
| 334 | |||
| 335 | Say "y" to link the driver statically, or "m" to build a | ||
| 336 | dynamically linked module called "imx_udc" and force all | ||
| 337 | gadget drivers to also be dynamically linked. | ||
| 338 | |||
| 339 | config USB_IMX | ||
| 340 | tristate | ||
| 341 | depends on USB_GADGET_IMX | ||
| 342 | default USB_GADGET | ||
| 343 | select USB_GADGET_SELECTED | ||
| 344 | |||
| 345 | config USB_GADGET_M66592 | 345 | config USB_GADGET_M66592 |
| 346 | boolean "Renesas M66592 USB Peripheral Controller" | 346 | boolean "Renesas M66592 USB Peripheral Controller" |
| 347 | select USB_GADGET_DUALSPEED | 347 | select USB_GADGET_DUALSPEED |
| @@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST | |||
| 604 | config USB_AUDIO | 604 | config USB_AUDIO |
| 605 | tristate "Audio Gadget (EXPERIMENTAL)" | 605 | tristate "Audio Gadget (EXPERIMENTAL)" |
| 606 | depends on SND | 606 | depends on SND |
| 607 | select SND_PCM | ||
| 607 | help | 608 | help |
| 608 | Gadget Audio is compatible with USB Audio Class specification 1.0. | 609 | Gadget Audio is compatible with USB Audio Class specification 1.0. |
| 609 | It will include at least one AudioControl interface, zero or more | 610 | It will include at least one AudioControl interface, zero or more |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 94de7e864614..9f80f4e970bd 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
| @@ -42,9 +42,9 @@ | |||
| 42 | * Instead: allocate your own, using normal USB-IF procedures. | 42 | * Instead: allocate your own, using normal USB-IF procedures. |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | /* Thanks to NetChip Technologies for donating this product ID. */ | 45 | /* Thanks to Linux Foundation for donating this product ID. */ |
| 46 | #define AUDIO_VENDOR_NUM 0x0525 /* NetChip */ | 46 | #define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */ |
| 47 | #define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */ | 47 | #define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */ |
| 48 | 48 | ||
| 49 | /*-------------------------------------------------------------------------*/ | 49 | /*-------------------------------------------------------------------------*/ |
| 50 | 50 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d006dc652e02..bd102f5052ba 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
| @@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
| 293 | /* CDC Subset */ | 293 | /* CDC Subset */ |
| 294 | eth_config_driver.label = "CDC Subset/SAFE"; | 294 | eth_config_driver.label = "CDC Subset/SAFE"; |
| 295 | 295 | ||
| 296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM), | 296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM); |
| 297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM), | 297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM); |
| 298 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 298 | if (!has_rndis()) |
| 299 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
| 299 | } | 300 | } |
| 300 | 301 | ||
| 301 | if (has_rndis()) { | 302 | if (has_rndis()) { |
| 302 | /* RNDIS plus ECM-or-Subset */ | 303 | /* RNDIS plus ECM-or-Subset */ |
| 303 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM), | 304 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM); |
| 304 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM), | 305 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM); |
| 305 | device_desc.bNumConfigurations = 2; | 306 | device_desc.bNumConfigurations = 2; |
| 306 | } | 307 | } |
| 307 | 308 | ||
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 0ce4e2819847..ed21e263f832 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
| @@ -139,7 +139,7 @@ static int is_vbus_present(void) | |||
| 139 | { | 139 | { |
| 140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
| 141 | 141 | ||
| 142 | if (mach->gpio_vbus) { | 142 | if (gpio_is_valid(mach->gpio_vbus)) { |
| 143 | int value = gpio_get_value(mach->gpio_vbus); | 143 | int value = gpio_get_value(mach->gpio_vbus); |
| 144 | 144 | ||
| 145 | if (mach->gpio_vbus_inverted) | 145 | if (mach->gpio_vbus_inverted) |
| @@ -158,7 +158,7 @@ static void pullup_off(void) | |||
| 158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
| 159 | int off_level = mach->gpio_pullup_inverted; | 159 | int off_level = mach->gpio_pullup_inverted; |
| 160 | 160 | ||
| 161 | if (mach->gpio_pullup) | 161 | if (gpio_is_valid(mach->gpio_pullup)) |
| 162 | gpio_set_value(mach->gpio_pullup, off_level); | 162 | gpio_set_value(mach->gpio_pullup, off_level); |
| 163 | else if (mach->udc_command) | 163 | else if (mach->udc_command) |
| 164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); |
| @@ -169,7 +169,7 @@ static void pullup_on(void) | |||
| 169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
| 170 | int on_level = !mach->gpio_pullup_inverted; | 170 | int on_level = !mach->gpio_pullup_inverted; |
| 171 | 171 | ||
| 172 | if (mach->gpio_pullup) | 172 | if (gpio_is_valid(mach->gpio_pullup)) |
| 173 | gpio_set_value(mach->gpio_pullup, on_level); | 173 | gpio_set_value(mach->gpio_pullup, on_level); |
| 174 | else if (mach->udc_command) | 174 | else if (mach->udc_command) |
| 175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | 175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); |
| @@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
| 1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | 1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); |
| 1001 | 1001 | ||
| 1002 | /* not all boards support pullup control */ | 1002 | /* not all boards support pullup control */ |
| 1003 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 1003 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
| 1004 | return -EOPNOTSUPP; | 1004 | return -EOPNOTSUPP; |
| 1005 | 1005 | ||
| 1006 | udc->pullup = (is_active != 0); | 1006 | udc->pullup = (is_active != 0); |
| @@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
| 1802 | USIR0 |= tmp; | 1802 | USIR0 |= tmp; |
| 1803 | handled = 1; | 1803 | handled = 1; |
| 1804 | } | 1804 | } |
| 1805 | #ifndef CONFIG_USB_PXA25X_SMALL | ||
| 1805 | if (usir1 & tmp) { | 1806 | if (usir1 & tmp) { |
| 1806 | handle_ep(&dev->ep[i+8]); | 1807 | handle_ep(&dev->ep[i+8]); |
| 1807 | USIR1 |= tmp; | 1808 | USIR1 |= tmp; |
| 1808 | handled = 1; | 1809 | handled = 1; |
| 1809 | } | 1810 | } |
| 1811 | #endif | ||
| 1810 | } | 1812 | } |
| 1811 | } | 1813 | } |
| 1812 | 1814 | ||
| @@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2160 | dev->dev = &pdev->dev; | 2162 | dev->dev = &pdev->dev; |
| 2161 | dev->mach = pdev->dev.platform_data; | 2163 | dev->mach = pdev->dev.platform_data; |
| 2162 | 2164 | ||
| 2163 | if (dev->mach->gpio_vbus) { | 2165 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
| 2164 | if ((retval = gpio_request(dev->mach->gpio_vbus, | 2166 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
| 2165 | "pxa25x_udc GPIO VBUS"))) { | 2167 | "pxa25x_udc GPIO VBUS"))) { |
| 2166 | dev_dbg(&pdev->dev, | 2168 | dev_dbg(&pdev->dev, |
| @@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
| 2173 | } else | 2175 | } else |
| 2174 | vbus_irq = 0; | 2176 | vbus_irq = 0; |
| 2175 | 2177 | ||
| 2176 | if (dev->mach->gpio_pullup) { | 2178 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
| 2177 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2179 | if ((retval = gpio_request(dev->mach->gpio_pullup, |
| 2178 | "pca25x_udc GPIO PULLUP"))) { | 2180 | "pca25x_udc GPIO PULLUP"))) { |
| 2179 | dev_dbg(&pdev->dev, | 2181 | dev_dbg(&pdev->dev, |
| @@ -2256,10 +2258,10 @@ lubbock_fail0: | |||
| 2256 | #endif | 2258 | #endif |
| 2257 | free_irq(irq, dev); | 2259 | free_irq(irq, dev); |
| 2258 | err_irq1: | 2260 | err_irq1: |
| 2259 | if (dev->mach->gpio_pullup) | 2261 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
| 2260 | gpio_free(dev->mach->gpio_pullup); | 2262 | gpio_free(dev->mach->gpio_pullup); |
| 2261 | err_gpio_pullup: | 2263 | err_gpio_pullup: |
| 2262 | if (dev->mach->gpio_vbus) | 2264 | if (gpio_is_valid(dev->mach->gpio_vbus)) |
| 2263 | gpio_free(dev->mach->gpio_vbus); | 2265 | gpio_free(dev->mach->gpio_vbus); |
| 2264 | err_gpio_vbus: | 2266 | err_gpio_vbus: |
| 2265 | clk_put(dev->clk); | 2267 | clk_put(dev->clk); |
| @@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
| 2294 | free_irq(LUBBOCK_USB_IRQ, dev); | 2296 | free_irq(LUBBOCK_USB_IRQ, dev); |
| 2295 | } | 2297 | } |
| 2296 | #endif | 2298 | #endif |
| 2297 | if (dev->mach->gpio_vbus) { | 2299 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
| 2298 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); | 2300 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); |
| 2299 | gpio_free(dev->mach->gpio_vbus); | 2301 | gpio_free(dev->mach->gpio_vbus); |
| 2300 | } | 2302 | } |
| 2301 | if (dev->mach->gpio_pullup) | 2303 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
| 2302 | gpio_free(dev->mach->gpio_pullup); | 2304 | gpio_free(dev->mach->gpio_pullup); |
| 2303 | 2305 | ||
| 2304 | clk_put(dev->clk); | 2306 | clk_put(dev->clk); |
| @@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
| 2329 | struct pxa25x_udc *udc = platform_get_drvdata(dev); | 2331 | struct pxa25x_udc *udc = platform_get_drvdata(dev); |
| 2330 | unsigned long flags; | 2332 | unsigned long flags; |
| 2331 | 2333 | ||
| 2332 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 2334 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
| 2333 | WARNING("USB host won't detect disconnect!\n"); | 2335 | WARNING("USB host won't detect disconnect!\n"); |
| 2334 | udc->suspended = 1; | 2336 | udc->suspended = 1; |
| 2335 | 2337 | ||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 2b4660e08c4d..ca41b0b5afb3 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
| @@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 442 | 442 | ||
| 443 | case OID_802_3_MAC_OPTIONS: | 443 | case OID_802_3_MAC_OPTIONS: |
| 444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); | 444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); |
| 445 | *outbuf = cpu_to_le32(0); | ||
| 446 | retval = 0; | ||
| 445 | break; | 447 | break; |
| 446 | 448 | ||
| 447 | /* ieee802.3 statistics OIDs (table 4-4) */ | 449 | /* ieee802.3 statistics OIDs (table 4-4) */ |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0c03471f0d41..1a920c70b5a1 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC | |||
| 181 | Enables support for the USB controller on the MPC52xx or | 181 | Enables support for the USB controller on the MPC52xx or |
| 182 | STB03xxx processor chip. If unsure, say Y. | 182 | STB03xxx processor chip. If unsure, say Y. |
| 183 | 183 | ||
| 184 | config USB_OHCI_HCD_PPC_OF | ||
| 185 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
| 186 | depends on USB_OHCI_HCD && PPC_OF | ||
| 187 | default y | ||
| 188 | ---help--- | ||
| 189 | Enables support for the USB controller PowerPC present on the | ||
| 190 | OpenFirmware platform bus. | ||
| 191 | |||
| 192 | config USB_OHCI_HCD_PPC_OF_BE | 184 | config USB_OHCI_HCD_PPC_OF_BE |
| 193 | bool "Support big endian HC" | 185 | bool "OHCI support for OF platform bus (big endian)" |
| 194 | depends on USB_OHCI_HCD_PPC_OF | 186 | depends on USB_OHCI_HCD && PPC_OF |
| 195 | default y | ||
| 196 | select USB_OHCI_BIG_ENDIAN_DESC | 187 | select USB_OHCI_BIG_ENDIAN_DESC |
| 197 | select USB_OHCI_BIG_ENDIAN_MMIO | 188 | select USB_OHCI_BIG_ENDIAN_MMIO |
| 189 | ---help--- | ||
| 190 | Enables support for big-endian USB controllers present on the | ||
| 191 | OpenFirmware platform bus. | ||
| 198 | 192 | ||
| 199 | config USB_OHCI_HCD_PPC_OF_LE | 193 | config USB_OHCI_HCD_PPC_OF_LE |
| 200 | bool "Support little endian HC" | 194 | bool "OHCI support for OF platform bus (little endian)" |
| 201 | depends on USB_OHCI_HCD_PPC_OF | 195 | depends on USB_OHCI_HCD && PPC_OF |
| 202 | default n | ||
| 203 | select USB_OHCI_LITTLE_ENDIAN | 196 | select USB_OHCI_LITTLE_ENDIAN |
| 197 | ---help--- | ||
| 198 | Enables support for little-endian USB controllers present on the | ||
| 199 | OpenFirmware platform bus. | ||
| 200 | |||
| 201 | config USB_OHCI_HCD_PPC_OF | ||
| 202 | bool | ||
| 203 | depends on USB_OHCI_HCD && PPC_OF | ||
| 204 | default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE | ||
| 204 | 205 | ||
| 205 | config USB_OHCI_HCD_PCI | 206 | config USB_OHCI_HCD_PCI |
| 206 | bool "OHCI support for PCI-bus USB controllers" | 207 | bool "OHCI support for PCI-bus USB controllers" |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index c3a778bd359c..59d208d94d4e 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
| @@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
| 113 | .bus_resume = ehci_bus_resume, | 113 | .bus_resume = ehci_bus_resume, |
| 114 | .relinquish_port = ehci_relinquish_port, | 114 | .relinquish_port = ehci_relinquish_port, |
| 115 | .port_handed_over = ehci_port_handed_over, | 115 | .port_handed_over = ehci_port_handed_over, |
| 116 | |||
| 117 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 116 | }; | 118 | }; |
| 117 | 119 | ||
| 118 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | 120 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index bf86809c5120..991174937db3 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
| @@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
| 325 | .bus_resume = ehci_bus_resume, | 325 | .bus_resume = ehci_bus_resume, |
| 326 | .relinquish_port = ehci_relinquish_port, | 326 | .relinquish_port = ehci_relinquish_port, |
| 327 | .port_handed_over = ehci_port_handed_over, | 327 | .port_handed_over = ehci_port_handed_over, |
| 328 | |||
| 329 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 328 | }; | 330 | }; |
| 329 | 331 | ||
| 330 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 332 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2b72473544d3..7d03549c3339 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -1003,6 +1003,8 @@ idle_timeout: | |||
| 1003 | schedule_timeout_uninterruptible(1); | 1003 | schedule_timeout_uninterruptible(1); |
| 1004 | goto rescan; | 1004 | goto rescan; |
| 1005 | case QH_STATE_IDLE: /* fully unlinked */ | 1005 | case QH_STATE_IDLE: /* fully unlinked */ |
| 1006 | if (qh->clearing_tt) | ||
| 1007 | goto idle_timeout; | ||
| 1006 | if (list_empty (&qh->qtd_list)) { | 1008 | if (list_empty (&qh->qtd_list)) { |
| 1007 | qh_put (qh); | 1009 | qh_put (qh); |
| 1008 | break; | 1010 | break; |
| @@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
| 1030 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 1032 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
| 1031 | struct ehci_qh *qh; | 1033 | struct ehci_qh *qh; |
| 1032 | int eptype = usb_endpoint_type(&ep->desc); | 1034 | int eptype = usb_endpoint_type(&ep->desc); |
| 1035 | int epnum = usb_endpoint_num(&ep->desc); | ||
| 1036 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
| 1037 | unsigned long flags; | ||
| 1033 | 1038 | ||
| 1034 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) | 1039 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) |
| 1035 | return; | 1040 | return; |
| 1036 | 1041 | ||
| 1037 | rescan: | 1042 | spin_lock_irqsave(&ehci->lock, flags); |
| 1038 | spin_lock_irq(&ehci->lock); | ||
| 1039 | qh = ep->hcpriv; | 1043 | qh = ep->hcpriv; |
| 1040 | 1044 | ||
| 1041 | /* For Bulk and Interrupt endpoints we maintain the toggle state | 1045 | /* For Bulk and Interrupt endpoints we maintain the toggle state |
| @@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
| 1044 | * the toggle bit in the QH. | 1048 | * the toggle bit in the QH. |
| 1045 | */ | 1049 | */ |
| 1046 | if (qh) { | 1050 | if (qh) { |
| 1051 | usb_settoggle(qh->dev, epnum, is_out, 0); | ||
| 1047 | if (!list_empty(&qh->qtd_list)) { | 1052 | if (!list_empty(&qh->qtd_list)) { |
| 1048 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); | 1053 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); |
| 1049 | } else if (qh->qh_state == QH_STATE_IDLE) { | 1054 | } else if (qh->qh_state == QH_STATE_LINKED) { |
| 1050 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | 1055 | |
| 1051 | } else { | 1056 | /* The toggle value in the QH can't be updated |
| 1052 | /* It's not safe to write into the overlay area | 1057 | * while the QH is active. Unlink it now; |
| 1053 | * while the QH is active. Unlink it first and | 1058 | * re-linking will call qh_refresh(). |
| 1054 | * wait for the unlink to complete. | ||
| 1055 | */ | 1059 | */ |
| 1056 | if (qh->qh_state == QH_STATE_LINKED) { | 1060 | if (eptype == USB_ENDPOINT_XFER_BULK) { |
| 1057 | if (eptype == USB_ENDPOINT_XFER_BULK) { | 1061 | unlink_async(ehci, qh); |
| 1058 | unlink_async(ehci, qh); | 1062 | } else { |
| 1059 | } else { | 1063 | intr_deschedule(ehci, qh); |
| 1060 | intr_deschedule(ehci, qh); | 1064 | (void) qh_schedule(ehci, qh); |
| 1061 | (void) qh_schedule(ehci, qh); | ||
| 1062 | } | ||
| 1063 | } | 1065 | } |
| 1064 | spin_unlock_irq(&ehci->lock); | ||
| 1065 | schedule_timeout_uninterruptible(1); | ||
| 1066 | goto rescan; | ||
| 1067 | } | 1066 | } |
| 1068 | } | 1067 | } |
| 1069 | spin_unlock_irq(&ehci->lock); | 1068 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 1070 | } | 1069 | } |
| 1071 | 1070 | ||
| 1072 | static int ehci_get_frame (struct usb_hcd *hcd) | 1071 | static int ehci_get_frame (struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index a44bb4a94954..89b7c70c6ed6 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
| @@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { | |||
| 61 | #endif | 61 | #endif |
| 62 | .relinquish_port = ehci_relinquish_port, | 62 | .relinquish_port = ehci_relinquish_port, |
| 63 | .port_handed_over = ehci_port_handed_over, | 63 | .port_handed_over = ehci_port_handed_over, |
| 64 | |||
| 65 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 64 | }; | 66 | }; |
| 65 | 67 | ||
| 66 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | 68 | static int ixp4xx_ehci_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 770dd9aba62a..dc2ac613a9d1 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
| @@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
| 165 | .bus_resume = ehci_bus_resume, | 165 | .bus_resume = ehci_bus_resume, |
| 166 | .relinquish_port = ehci_relinquish_port, | 166 | .relinquish_port = ehci_relinquish_port, |
| 167 | .port_handed_over = ehci_port_handed_over, | 167 | .port_handed_over = ehci_port_handed_over, |
| 168 | |||
| 169 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 168 | }; | 170 | }; |
| 169 | 171 | ||
| 170 | static void __init | 172 | static void __init |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index f3683e1da161..c2f1b7df918c 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
| 404 | .bus_resume = ehci_bus_resume, | 404 | .bus_resume = ehci_bus_resume, |
| 405 | .relinquish_port = ehci_relinquish_port, | 405 | .relinquish_port = ehci_relinquish_port, |
| 406 | .port_handed_over = ehci_port_handed_over, | 406 | .port_handed_over = ehci_port_handed_over, |
| 407 | |||
| 408 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 407 | }; | 409 | }; |
| 408 | 410 | ||
| 409 | /*-------------------------------------------------------------------------*/ | 411 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index fbd272288fc2..36f96da129f5 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
| @@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { | |||
| 79 | #endif | 79 | #endif |
| 80 | .relinquish_port = ehci_relinquish_port, | 80 | .relinquish_port = ehci_relinquish_port, |
| 81 | .port_handed_over = ehci_port_handed_over, | 81 | .port_handed_over = ehci_port_handed_over, |
| 82 | |||
| 83 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | 86 | ||
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 93f7035d00a1..1dee33b9139e 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
| @@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
| 75 | #endif | 75 | #endif |
| 76 | .relinquish_port = ehci_relinquish_port, | 76 | .relinquish_port = ehci_relinquish_port, |
| 77 | .port_handed_over = ehci_port_handed_over, | 77 | .port_handed_over = ehci_port_handed_over, |
| 78 | |||
| 79 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 78 | }; | 80 | }; |
| 79 | 81 | ||
| 80 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) | 82 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3192f683f807..9a1384747f3b 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) | |||
| 93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); | 93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); |
| 94 | qh->hw_alt_next = EHCI_LIST_END(ehci); | 94 | qh->hw_alt_next = EHCI_LIST_END(ehci); |
| 95 | 95 | ||
| 96 | /* Except for control endpoints, we make hardware maintain data | ||
| 97 | * toggle (like OHCI) ... here (re)initialize the toggle in the QH, | ||
| 98 | * and set the pseudo-toggle in udev. Only usb_clear_halt() will | ||
| 99 | * ever clear it. | ||
| 100 | */ | ||
| 101 | if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { | ||
| 102 | unsigned is_out, epnum; | ||
| 103 | |||
| 104 | is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); | ||
| 105 | epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f; | ||
| 106 | if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { | ||
| 107 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | ||
| 108 | usb_settoggle (qh->dev, epnum, is_out, 1); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 96 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 112 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
| 97 | wmb (); | 113 | wmb (); |
| 98 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); | 114 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); |
| @@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 123 | 139 | ||
| 124 | /*-------------------------------------------------------------------------*/ | 140 | /*-------------------------------------------------------------------------*/ |
| 125 | 141 | ||
| 142 | static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh); | ||
| 143 | |||
| 144 | static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd, | ||
| 145 | struct usb_host_endpoint *ep) | ||
| 146 | { | ||
| 147 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 148 | struct ehci_qh *qh = ep->hcpriv; | ||
| 149 | unsigned long flags; | ||
| 150 | |||
| 151 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 152 | qh->clearing_tt = 0; | ||
| 153 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) | ||
| 154 | && HC_IS_RUNNING(hcd->state)) | ||
| 155 | qh_link_async(ehci, qh); | ||
| 156 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh, | ||
| 160 | struct urb *urb, u32 token) | ||
| 161 | { | ||
| 162 | |||
| 163 | /* If an async split transaction gets an error or is unlinked, | ||
| 164 | * the TT buffer may be left in an indeterminate state. We | ||
| 165 | * have to clear the TT buffer. | ||
| 166 | * | ||
| 167 | * Note: this routine is never called for Isochronous transfers. | ||
| 168 | */ | ||
| 169 | if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { | ||
| 170 | #ifdef DEBUG | ||
| 171 | struct usb_device *tt = urb->dev->tt->hub; | ||
| 172 | dev_dbg(&tt->dev, | ||
| 173 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
| 174 | urb->dev->ttport, urb->dev->devnum, | ||
| 175 | usb_pipeendpoint(urb->pipe), token); | ||
| 176 | #endif /* DEBUG */ | ||
| 177 | if (!ehci_is_TDI(ehci) | ||
| 178 | || urb->dev->tt->hub != | ||
| 179 | ehci_to_hcd(ehci)->self.root_hub) { | ||
| 180 | if (usb_hub_clear_tt_buffer(urb) == 0) | ||
| 181 | qh->clearing_tt = 1; | ||
| 182 | } else { | ||
| 183 | |||
| 184 | /* REVISIT ARC-derived cores don't clear the root | ||
| 185 | * hub TT buffer in this way... | ||
| 186 | */ | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 126 | static int qtd_copy_status ( | 191 | static int qtd_copy_status ( |
| 127 | struct ehci_hcd *ehci, | 192 | struct ehci_hcd *ehci, |
| 128 | struct urb *urb, | 193 | struct urb *urb, |
| @@ -149,6 +214,14 @@ static int qtd_copy_status ( | |||
| 149 | if (token & QTD_STS_BABBLE) { | 214 | if (token & QTD_STS_BABBLE) { |
| 150 | /* FIXME "must" disable babbling device's port too */ | 215 | /* FIXME "must" disable babbling device's port too */ |
| 151 | status = -EOVERFLOW; | 216 | status = -EOVERFLOW; |
| 217 | /* CERR nonzero + halt --> stall */ | ||
| 218 | } else if (QTD_CERR(token)) { | ||
| 219 | status = -EPIPE; | ||
| 220 | |||
| 221 | /* In theory, more than one of the following bits can be set | ||
| 222 | * since they are sticky and the transaction is retried. | ||
| 223 | * Which to test first is rather arbitrary. | ||
| 224 | */ | ||
| 152 | } else if (token & QTD_STS_MMF) { | 225 | } else if (token & QTD_STS_MMF) { |
| 153 | /* fs/ls interrupt xfer missed the complete-split */ | 226 | /* fs/ls interrupt xfer missed the complete-split */ |
| 154 | status = -EPROTO; | 227 | status = -EPROTO; |
| @@ -157,21 +230,15 @@ static int qtd_copy_status ( | |||
| 157 | ? -ENOSR /* hc couldn't read data */ | 230 | ? -ENOSR /* hc couldn't read data */ |
| 158 | : -ECOMM; /* hc couldn't write data */ | 231 | : -ECOMM; /* hc couldn't write data */ |
| 159 | } else if (token & QTD_STS_XACT) { | 232 | } else if (token & QTD_STS_XACT) { |
| 160 | /* timeout, bad crc, wrong PID, etc; retried */ | 233 | /* timeout, bad CRC, wrong PID, etc */ |
| 161 | if (QTD_CERR (token)) | 234 | ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n", |
| 162 | status = -EPIPE; | 235 | urb->dev->devpath, |
| 163 | else { | 236 | usb_pipeendpoint(urb->pipe), |
| 164 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", | 237 | usb_pipein(urb->pipe) ? "in" : "out"); |
| 165 | urb->dev->devpath, | 238 | status = -EPROTO; |
| 166 | usb_pipeendpoint (urb->pipe), | 239 | } else { /* unknown */ |
| 167 | usb_pipein (urb->pipe) ? "in" : "out"); | ||
| 168 | status = -EPROTO; | ||
| 169 | } | ||
| 170 | /* CERR nonzero + no errors + halt --> stall */ | ||
| 171 | } else if (QTD_CERR (token)) | ||
| 172 | status = -EPIPE; | ||
| 173 | else /* unknown */ | ||
| 174 | status = -EPROTO; | 240 | status = -EPROTO; |
| 241 | } | ||
| 175 | 242 | ||
| 176 | ehci_vdbg (ehci, | 243 | ehci_vdbg (ehci, |
| 177 | "dev%d ep%d%s qtd token %08x --> status %d\n", | 244 | "dev%d ep%d%s qtd token %08x --> status %d\n", |
| @@ -179,28 +246,6 @@ static int qtd_copy_status ( | |||
| 179 | usb_pipeendpoint (urb->pipe), | 246 | usb_pipeendpoint (urb->pipe), |
| 180 | usb_pipein (urb->pipe) ? "in" : "out", | 247 | usb_pipein (urb->pipe) ? "in" : "out", |
| 181 | token, status); | 248 | token, status); |
| 182 | |||
| 183 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | ||
| 184 | if (status != -EPIPE | ||
| 185 | && urb->dev->tt | ||
| 186 | && !usb_pipeint(urb->pipe) | ||
| 187 | && ((token & QTD_STS_MMF) != 0 | ||
| 188 | || QTD_CERR(token) == 0) | ||
| 189 | && (!ehci_is_TDI(ehci) | ||
| 190 | || urb->dev->tt->hub != | ||
| 191 | ehci_to_hcd(ehci)->self.root_hub)) { | ||
| 192 | #ifdef DEBUG | ||
| 193 | struct usb_device *tt = urb->dev->tt->hub; | ||
| 194 | dev_dbg (&tt->dev, | ||
| 195 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
| 196 | urb->dev->ttport, urb->dev->devnum, | ||
| 197 | usb_pipeendpoint (urb->pipe), token); | ||
| 198 | #endif /* DEBUG */ | ||
| 199 | /* REVISIT ARC-derived cores don't clear the root | ||
| 200 | * hub TT buffer in this way... | ||
| 201 | */ | ||
| 202 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | ||
| 203 | } | ||
| 204 | } | 249 | } |
| 205 | 250 | ||
| 206 | return status; | 251 | return status; |
| @@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 391 | /* qh unlinked; token in overlay may be most current */ | 436 | /* qh unlinked; token in overlay may be most current */ |
| 392 | if (state == QH_STATE_IDLE | 437 | if (state == QH_STATE_IDLE |
| 393 | && cpu_to_hc32(ehci, qtd->qtd_dma) | 438 | && cpu_to_hc32(ehci, qtd->qtd_dma) |
| 394 | == qh->hw_current) | 439 | == qh->hw_current) { |
| 395 | token = hc32_to_cpu(ehci, qh->hw_token); | 440 | token = hc32_to_cpu(ehci, qh->hw_token); |
| 396 | 441 | ||
| 442 | /* An unlink may leave an incomplete | ||
| 443 | * async transaction in the TT buffer. | ||
| 444 | * We have to clear it. | ||
| 445 | */ | ||
| 446 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
| 447 | } | ||
| 448 | |||
| 397 | /* force halt for unlinked or blocked qh, so we'll | 449 | /* force halt for unlinked or blocked qh, so we'll |
| 398 | * patch the qh later and so that completions can't | 450 | * patch the qh later and so that completions can't |
| 399 | * activate it while we "know" it's stopped. | 451 | * activate it while we "know" it's stopped. |
| @@ -419,6 +471,13 @@ halt: | |||
| 419 | && (qtd->hw_alt_next | 471 | && (qtd->hw_alt_next |
| 420 | & EHCI_LIST_END(ehci))) | 472 | & EHCI_LIST_END(ehci))) |
| 421 | last_status = -EINPROGRESS; | 473 | last_status = -EINPROGRESS; |
| 474 | |||
| 475 | /* As part of low/full-speed endpoint-halt processing | ||
| 476 | * we must clear the TT buffer (11.17.5). | ||
| 477 | */ | ||
| 478 | if (unlikely(last_status != -EINPROGRESS && | ||
| 479 | last_status != -EREMOTEIO)) | ||
| 480 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
| 422 | } | 481 | } |
| 423 | 482 | ||
| 424 | /* if we're removing something not at the queue head, | 483 | /* if we're removing something not at the queue head, |
| @@ -834,6 +893,7 @@ done: | |||
| 834 | qh->qh_state = QH_STATE_IDLE; | 893 | qh->qh_state = QH_STATE_IDLE; |
| 835 | qh->hw_info1 = cpu_to_hc32(ehci, info1); | 894 | qh->hw_info1 = cpu_to_hc32(ehci, info1); |
| 836 | qh->hw_info2 = cpu_to_hc32(ehci, info2); | 895 | qh->hw_info2 = cpu_to_hc32(ehci, info2); |
| 896 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); | ||
| 837 | qh_refresh (ehci, qh); | 897 | qh_refresh (ehci, qh); |
| 838 | return qh; | 898 | return qh; |
| 839 | } | 899 | } |
| @@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 847 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); | 907 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); |
| 848 | struct ehci_qh *head; | 908 | struct ehci_qh *head; |
| 849 | 909 | ||
| 910 | /* Don't link a QH if there's a Clear-TT-Buffer pending */ | ||
| 911 | if (unlikely(qh->clearing_tt)) | ||
| 912 | return; | ||
| 913 | |||
| 850 | /* (re)start the async schedule? */ | 914 | /* (re)start the async schedule? */ |
| 851 | head = ehci->async; | 915 | head = ehci->async; |
| 852 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 916 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
| @@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 864 | } | 928 | } |
| 865 | } | 929 | } |
| 866 | 930 | ||
| 867 | /* clear halt and maybe recover from silicon quirk */ | 931 | /* clear halt and/or toggle; and maybe recover from silicon quirk */ |
| 868 | if (qh->qh_state == QH_STATE_IDLE) | 932 | if (qh->qh_state == QH_STATE_IDLE) |
| 869 | qh_refresh (ehci, qh); | 933 | qh_refresh (ehci, qh); |
| 870 | 934 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 9d1babc7ff65..74f7f83b29ad 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1619,11 +1619,14 @@ itd_complete ( | |||
| 1619 | desc->status = -EPROTO; | 1619 | desc->status = -EPROTO; |
| 1620 | 1620 | ||
| 1621 | /* HC need not update length with this error */ | 1621 | /* HC need not update length with this error */ |
| 1622 | if (!(t & EHCI_ISOC_BABBLE)) | 1622 | if (!(t & EHCI_ISOC_BABBLE)) { |
| 1623 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1623 | desc->actual_length = EHCI_ITD_LENGTH(t); |
| 1624 | urb->actual_length += desc->actual_length; | ||
| 1625 | } | ||
| 1624 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { | 1626 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { |
| 1625 | desc->status = 0; | 1627 | desc->status = 0; |
| 1626 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1628 | desc->actual_length = EHCI_ITD_LENGTH(t); |
| 1629 | urb->actual_length += desc->actual_length; | ||
| 1627 | } else { | 1630 | } else { |
| 1628 | /* URB was too late */ | 1631 | /* URB was too late */ |
| 1629 | desc->status = -EXDEV; | 1632 | desc->status = -EXDEV; |
| @@ -2014,7 +2017,8 @@ sitd_complete ( | |||
| 2014 | desc->status = -EPROTO; | 2017 | desc->status = -EPROTO; |
| 2015 | } else { | 2018 | } else { |
| 2016 | desc->status = 0; | 2019 | desc->status = 0; |
| 2017 | desc->actual_length = desc->length - SITD_LENGTH (t); | 2020 | desc->actual_length = desc->length - SITD_LENGTH(t); |
| 2021 | urb->actual_length += desc->actual_length; | ||
| 2018 | } | 2022 | } |
| 2019 | stream->depth -= stream->interval << 3; | 2023 | stream->depth -= stream->interval << 3; |
| 2020 | 2024 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 90ad3395bb21..2bfff30f4704 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -354,7 +354,9 @@ struct ehci_qh { | |||
| 354 | unsigned short period; /* polling interval */ | 354 | unsigned short period; /* polling interval */ |
| 355 | unsigned short start; /* where polling starts */ | 355 | unsigned short start; /* where polling starts */ |
| 356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
| 357 | |||
| 357 | struct usb_device *dev; /* access to TT */ | 358 | struct usb_device *dev; /* access to TT */ |
| 359 | unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ | ||
| 358 | } __attribute__ ((aligned (32))); | 360 | } __attribute__ ((aligned (32))); |
| 359 | 361 | ||
| 360 | /*-------------------------------------------------------------------------*/ | 362 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index bb63b68ddb77..62a226b61670 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c | |||
| @@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
| 576 | out_be16(&usb->fhci->regs->usb_event, | 576 | out_be16(&usb->fhci->regs->usb_event, |
| 577 | usb->saved_msk); | 577 | usb->saved_msk); |
| 578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { | 578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { |
| 579 | if (fhci_ioports_check_bus_state(fhci) == 1 && | 579 | if (fhci_ioports_check_bus_state(fhci) == 1) |
| 580 | usb->port_status != FHCI_PORT_LOW && | ||
| 581 | usb->port_status != FHCI_PORT_FULL) | ||
| 582 | fhci_device_connected_interrupt(fhci); | 580 | fhci_device_connected_interrupt(fhci); |
| 583 | } | 581 | } |
| 584 | usb_er &= ~USB_E_RESET_MASK; | 582 | usb_er &= ~USB_E_RESET_MASK; |
| @@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
| 605 | } | 603 | } |
| 606 | 604 | ||
| 607 | if (usb_er & USB_E_IDLE_MASK) { | 605 | if (usb_er & USB_E_IDLE_MASK) { |
| 608 | if (usb->port_status == FHCI_PORT_DISABLED && | 606 | if (usb->port_status == FHCI_PORT_DISABLED) { |
| 609 | usb->port_status != FHCI_PORT_LOW && | ||
| 610 | usb->port_status != FHCI_PORT_FULL) { | ||
| 611 | usb_er &= ~USB_E_RESET_MASK; | 607 | usb_er &= ~USB_E_RESET_MASK; |
| 612 | fhci_device_connected_interrupt(fhci); | 608 | fhci_device_connected_interrupt(fhci); |
| 613 | } else if (usb->port_status == | 609 | } else if (usb->port_status == |
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3fa3a1702796..d4feebfc63bd 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
| @@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev) | |||
| 361 | 361 | ||
| 362 | static struct platform_driver isp1760_plat_driver = { | 362 | static struct platform_driver isp1760_plat_driver = { |
| 363 | .probe = isp1760_plat_probe, | 363 | .probe = isp1760_plat_probe, |
| 364 | .remove = isp1760_plat_remove, | 364 | .remove = __devexit_p(isp1760_plat_remove), |
| 365 | .driver = { | 365 | .driver = { |
| 366 | .name = "isp1760", | 366 | .name = "isp1760", |
| 367 | }, | 367 | }, |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 180d7daa4099..e16ff605c458 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -35,13 +35,14 @@ | |||
| 35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
| 36 | #include <mach/memory.h> | 36 | #include <mach/memory.h> |
| 37 | #include <mach/gpio.h> | 37 | #include <mach/gpio.h> |
| 38 | #include <mach/cputype.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
| 40 | 41 | ||
| 41 | #include "musb_core.h" | 42 | #include "musb_core.h" |
| 42 | 43 | ||
| 43 | #ifdef CONFIG_MACH_DAVINCI_EVM | 44 | #ifdef CONFIG_MACH_DAVINCI_EVM |
| 44 | #define GPIO_nVBUS_DRV 87 | 45 | #define GPIO_nVBUS_DRV 144 |
| 45 | #endif | 46 | #endif |
| 46 | 47 | ||
| 47 | #include "davinci.h" | 48 | #include "davinci.h" |
| @@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
| 329 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 330 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
| 330 | WARNING("VBUS error workaround (delay coming)\n"); | 331 | WARNING("VBUS error workaround (delay coming)\n"); |
| 331 | } else if (is_host_enabled(musb) && drvvbus) { | 332 | } else if (is_host_enabled(musb) && drvvbus) { |
| 332 | musb->is_active = 1; | ||
| 333 | MUSB_HST_MODE(musb); | 333 | MUSB_HST_MODE(musb); |
| 334 | musb->xceiv->default_a = 1; | 334 | musb->xceiv->default_a = 1; |
| 335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
| @@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
| 343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | 343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | /* NOTE: this must complete poweron within 100 msec */ | 346 | /* NOTE: this must complete poweron within 100 msec |
| 347 | * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. | ||
| 348 | */ | ||
| 347 | davinci_source_power(musb, drvvbus, 0); | 349 | davinci_source_power(musb, drvvbus, 0); |
| 348 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | 350 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", |
| 349 | drvvbus ? "on" : "off", | 351 | drvvbus ? "on" : "off", |
| @@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb) | |||
| 411 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | 413 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
| 412 | } | 414 | } |
| 413 | 415 | ||
| 416 | /* On dm355, the default-A state machine needs DRVVBUS control. | ||
| 417 | * If we won't be a host, there's no need to turn it on. | ||
| 418 | */ | ||
| 419 | if (cpu_is_davinci_dm355()) { | ||
| 420 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
| 421 | |||
| 422 | if (is_host_enabled(musb)) { | ||
| 423 | deepsleep &= ~DRVVBUS_OVERRIDE; | ||
| 424 | } else { | ||
| 425 | deepsleep &= ~DRVVBUS_FORCE; | ||
| 426 | deepsleep |= DRVVBUS_OVERRIDE; | ||
| 427 | } | ||
| 428 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
| 429 | } | ||
| 430 | |||
| 414 | /* reset the controller */ | 431 | /* reset the controller */ |
| 415 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 432 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
| 416 | 433 | ||
| @@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb) | |||
| 437 | if (is_host_enabled(musb)) | 454 | if (is_host_enabled(musb)) |
| 438 | del_timer_sync(&otg_workaround); | 455 | del_timer_sync(&otg_workaround); |
| 439 | 456 | ||
| 457 | /* force VBUS off */ | ||
| 458 | if (cpu_is_davinci_dm355()) { | ||
| 459 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
| 460 | |||
| 461 | deepsleep &= ~DRVVBUS_FORCE; | ||
| 462 | deepsleep |= DRVVBUS_OVERRIDE; | ||
| 463 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
| 464 | } | ||
| 465 | |||
| 440 | davinci_source_power(musb, 0 /*off*/, 1); | 466 | davinci_source_power(musb, 0 /*off*/, 1); |
| 441 | 467 | ||
| 442 | /* delay, to avoid problems with module reload */ | 468 | /* delay, to avoid problems with module reload */ |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 94a2a350a414..cf94511485f2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
| 373 | musb_save_toggle(qh, is_in, urb); | 373 | musb_save_toggle(qh, is_in, urb); |
| 374 | break; | 374 | break; |
| 375 | case USB_ENDPOINT_XFER_ISOC: | 375 | case USB_ENDPOINT_XFER_ISOC: |
| 376 | if (urb->error_count) | 376 | if (status == 0 && urb->error_count) |
| 377 | status = -EXDEV; | 377 | status = -EXDEV; |
| 378 | break; | 378 | break; |
| 379 | } | 379 | } |
| @@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd) | |||
| 2235 | static int musb_bus_suspend(struct usb_hcd *hcd) | 2235 | static int musb_bus_suspend(struct usb_hcd *hcd) |
| 2236 | { | 2236 | { |
| 2237 | struct musb *musb = hcd_to_musb(hcd); | 2237 | struct musb *musb = hcd_to_musb(hcd); |
| 2238 | u8 devctl; | ||
| 2238 | 2239 | ||
| 2239 | if (musb->xceiv->state == OTG_STATE_A_SUSPEND) | 2240 | if (!is_host_active(musb)) |
| 2240 | return 0; | 2241 | return 0; |
| 2241 | 2242 | ||
| 2242 | if (is_host_active(musb) && musb->is_active) { | 2243 | switch (musb->xceiv->state) { |
| 2243 | WARNING("trying to suspend as %s is_active=%i\n", | 2244 | case OTG_STATE_A_SUSPEND: |
| 2244 | otg_state_string(musb), musb->is_active); | 2245 | return 0; |
| 2246 | case OTG_STATE_A_WAIT_VRISE: | ||
| 2247 | /* ID could be grounded even if there's no device | ||
| 2248 | * on the other end of the cable. NOTE that the | ||
| 2249 | * A_WAIT_VRISE timers are messy with MUSB... | ||
| 2250 | */ | ||
| 2251 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 2252 | if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) | ||
| 2253 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
| 2254 | break; | ||
| 2255 | default: | ||
| 2256 | break; | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | if (musb->is_active) { | ||
| 2260 | WARNING("trying to suspend as %s while active\n", | ||
| 2261 | otg_state_string(musb)); | ||
| 2245 | return -EBUSY; | 2262 | return -EBUSY; |
| 2246 | } else | 2263 | } else |
| 2247 | return 0; | 2264 | return 0; |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 69feeec1628c..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -59,18 +59,4 @@ config NOP_USB_XCEIV | |||
| 59 | built-in with usb ip or which are autonomous and doesn't require any | 59 | built-in with usb ip or which are autonomous and doesn't require any |
| 60 | phy programming such as ISP1x04 etc. | 60 | phy programming such as ISP1x04 etc. |
| 61 | 61 | ||
| 62 | config USB_LANGWELL_OTG | ||
| 63 | tristate "Intel Langwell USB OTG dual-role support" | ||
| 64 | depends on USB && MRST | ||
| 65 | select USB_OTG | ||
| 66 | select USB_OTG_UTILS | ||
| 67 | help | ||
| 68 | Say Y here if you want to build Intel Langwell USB OTG | ||
| 69 | transciever driver in kernel. This driver implements role | ||
| 70 | switch between EHCI host driver and Langwell USB OTG | ||
| 71 | client driver. | ||
| 72 | |||
| 73 | To compile this driver as a module, choose M here: the | ||
| 74 | module will be called langwell_otg. | ||
| 75 | |||
| 76 | endif # USB || OTG | 62 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index 6d1abdd3c0ac..208167856529 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
| @@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
| 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
| 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
| 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
| 12 | obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o | ||
| 13 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | 12 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o |
| 14 | 13 | ||
| 15 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG |
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c deleted file mode 100644 index 6f628d0e9f39..000000000000 --- a/drivers/usb/otg/langwell_otg.c +++ /dev/null | |||
| @@ -1,1915 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Intel Langwell USB OTG transceiver driver | ||
| 3 | * Copyright (C) 2008 - 2009, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | /* This driver helps to switch Langwell OTG controller function between host | ||
| 20 | * and peripheral. It works with EHCI driver and Langwell client controller | ||
| 21 | * driver together. | ||
| 22 | */ | ||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/pci.h> | ||
| 26 | #include <linux/errno.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/kernel.h> | ||
| 29 | #include <linux/device.h> | ||
| 30 | #include <linux/moduleparam.h> | ||
| 31 | #include <linux/usb/ch9.h> | ||
| 32 | #include <linux/usb/gadget.h> | ||
| 33 | #include <linux/usb.h> | ||
| 34 | #include <linux/usb/otg.h> | ||
| 35 | #include <linux/notifier.h> | ||
| 36 | #include <asm/ipc_defs.h> | ||
| 37 | #include <linux/delay.h> | ||
| 38 | #include "../core/hcd.h" | ||
| 39 | |||
| 40 | #include <linux/usb/langwell_otg.h> | ||
| 41 | |||
| 42 | #define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" | ||
| 43 | #define DRIVER_VERSION "3.0.0.32L.0002" | ||
| 44 | |||
| 45 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 46 | MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>"); | ||
| 47 | MODULE_VERSION(DRIVER_VERSION); | ||
| 48 | MODULE_LICENSE("GPL"); | ||
| 49 | |||
| 50 | static const char driver_name[] = "langwell_otg"; | ||
| 51 | |||
| 52 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
| 53 | const struct pci_device_id *id); | ||
| 54 | static void langwell_otg_remove(struct pci_dev *pdev); | ||
| 55 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); | ||
| 56 | static int langwell_otg_resume(struct pci_dev *pdev); | ||
| 57 | |||
| 58 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
| 59 | struct usb_bus *host); | ||
| 60 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
| 61 | struct usb_gadget *gadget); | ||
| 62 | static int langwell_otg_start_srp(struct otg_transceiver *otg); | ||
| 63 | |||
| 64 | static const struct pci_device_id pci_ids[] = {{ | ||
| 65 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
| 66 | .class_mask = ~0, | ||
| 67 | .vendor = 0x8086, | ||
| 68 | .device = 0x0811, | ||
| 69 | .subvendor = PCI_ANY_ID, | ||
| 70 | .subdevice = PCI_ANY_ID, | ||
| 71 | }, { /* end: all zeroes */ } | ||
| 72 | }; | ||
| 73 | |||
| 74 | static struct pci_driver otg_pci_driver = { | ||
| 75 | .name = (char *) driver_name, | ||
| 76 | .id_table = pci_ids, | ||
| 77 | |||
| 78 | .probe = langwell_otg_probe, | ||
| 79 | .remove = langwell_otg_remove, | ||
| 80 | |||
| 81 | .suspend = langwell_otg_suspend, | ||
| 82 | .resume = langwell_otg_resume, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static const char *state_string(enum usb_otg_state state) | ||
| 86 | { | ||
| 87 | switch (state) { | ||
| 88 | case OTG_STATE_A_IDLE: | ||
| 89 | return "a_idle"; | ||
| 90 | case OTG_STATE_A_WAIT_VRISE: | ||
| 91 | return "a_wait_vrise"; | ||
| 92 | case OTG_STATE_A_WAIT_BCON: | ||
| 93 | return "a_wait_bcon"; | ||
| 94 | case OTG_STATE_A_HOST: | ||
| 95 | return "a_host"; | ||
| 96 | case OTG_STATE_A_SUSPEND: | ||
| 97 | return "a_suspend"; | ||
| 98 | case OTG_STATE_A_PERIPHERAL: | ||
| 99 | return "a_peripheral"; | ||
| 100 | case OTG_STATE_A_WAIT_VFALL: | ||
| 101 | return "a_wait_vfall"; | ||
| 102 | case OTG_STATE_A_VBUS_ERR: | ||
| 103 | return "a_vbus_err"; | ||
| 104 | case OTG_STATE_B_IDLE: | ||
| 105 | return "b_idle"; | ||
| 106 | case OTG_STATE_B_SRP_INIT: | ||
| 107 | return "b_srp_init"; | ||
| 108 | case OTG_STATE_B_PERIPHERAL: | ||
| 109 | return "b_peripheral"; | ||
| 110 | case OTG_STATE_B_WAIT_ACON: | ||
| 111 | return "b_wait_acon"; | ||
| 112 | case OTG_STATE_B_HOST: | ||
| 113 | return "b_host"; | ||
| 114 | default: | ||
| 115 | return "UNDEFINED"; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | /* HSM timers */ | ||
| 120 | static inline struct langwell_otg_timer *otg_timer_initializer | ||
| 121 | (void (*function)(unsigned long), unsigned long expires, unsigned long data) | ||
| 122 | { | ||
| 123 | struct langwell_otg_timer *timer; | ||
| 124 | timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); | ||
| 125 | timer->function = function; | ||
| 126 | timer->expires = expires; | ||
| 127 | timer->data = data; | ||
| 128 | return timer; | ||
| 129 | } | ||
| 130 | |||
| 131 | static struct langwell_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, | ||
| 132 | *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_res_tmr, | ||
| 133 | *b_bus_suspend_tmr; | ||
| 134 | |||
| 135 | static struct list_head active_timers; | ||
| 136 | |||
| 137 | static struct langwell_otg *the_transceiver; | ||
| 138 | |||
| 139 | /* host/client notify transceiver when event affects HNP state */ | ||
| 140 | void langwell_update_transceiver() | ||
| 141 | { | ||
| 142 | otg_dbg("transceiver driver is notified\n"); | ||
| 143 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
| 144 | } | ||
| 145 | EXPORT_SYMBOL(langwell_update_transceiver); | ||
| 146 | |||
| 147 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
| 148 | struct usb_bus *host) | ||
| 149 | { | ||
| 150 | otg->host = host; | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
| 156 | struct usb_gadget *gadget) | ||
| 157 | { | ||
| 158 | otg->gadget = gadget; | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int langwell_otg_set_power(struct otg_transceiver *otg, | ||
| 164 | unsigned mA) | ||
| 165 | { | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | /* A-device drives vbus, controlled through PMIC CHRGCNTL register*/ | ||
| 170 | static void langwell_otg_drv_vbus(int on) | ||
| 171 | { | ||
| 172 | struct ipc_pmic_reg_data pmic_data = {0}; | ||
| 173 | struct ipc_pmic_reg_data battery_data; | ||
| 174 | |||
| 175 | /* Check if battery is attached or not */ | ||
| 176 | battery_data.pmic_reg_data[0].register_address = 0xd2; | ||
| 177 | battery_data.ioc = 0; | ||
| 178 | battery_data.num_entries = 1; | ||
| 179 | if (ipc_pmic_register_read(&battery_data)) { | ||
| 180 | otg_dbg("Failed to read PMIC register 0xd2.\n"); | ||
| 181 | return; | ||
| 182 | } | ||
| 183 | |||
| 184 | if ((battery_data.pmic_reg_data[0].value & 0x20) == 0) { | ||
| 185 | otg_dbg("no battery attached\n"); | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | |||
| 189 | /* Workaround for battery attachment issue */ | ||
| 190 | if (battery_data.pmic_reg_data[0].value == 0x34) { | ||
| 191 | otg_dbg("battery \n"); | ||
| 192 | return; | ||
| 193 | } | ||
| 194 | |||
| 195 | otg_dbg("battery attached\n"); | ||
| 196 | |||
| 197 | pmic_data.ioc = 0; | ||
| 198 | pmic_data.pmic_reg_data[0].register_address = 0xD4; | ||
| 199 | pmic_data.num_entries = 1; | ||
| 200 | if (on) | ||
| 201 | pmic_data.pmic_reg_data[0].value = 0x20; | ||
| 202 | else | ||
| 203 | pmic_data.pmic_reg_data[0].value = 0xc0; | ||
| 204 | |||
| 205 | if (ipc_pmic_register_write(&pmic_data, TRUE)) | ||
| 206 | otg_dbg("Failed to write PMIC.\n"); | ||
| 207 | |||
| 208 | } | ||
| 209 | |||
| 210 | /* charge vbus or discharge vbus through a resistor to ground */ | ||
| 211 | static void langwell_otg_chrg_vbus(int on) | ||
| 212 | { | ||
| 213 | |||
| 214 | u32 val; | ||
| 215 | |||
| 216 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 217 | |||
| 218 | if (on) | ||
| 219 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, | ||
| 220 | the_transceiver->regs + CI_OTGSC); | ||
| 221 | else | ||
| 222 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, | ||
| 223 | the_transceiver->regs + CI_OTGSC); | ||
| 224 | |||
| 225 | } | ||
| 226 | |||
| 227 | /* Start SRP */ | ||
| 228 | static int langwell_otg_start_srp(struct otg_transceiver *otg) | ||
| 229 | { | ||
| 230 | u32 val; | ||
| 231 | |||
| 232 | otg_dbg("Start SRP ->\n"); | ||
| 233 | |||
| 234 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 235 | |||
| 236 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, | ||
| 237 | the_transceiver->regs + CI_OTGSC); | ||
| 238 | |||
| 239 | /* Check if the data plus is finished or not */ | ||
| 240 | msleep(8); | ||
| 241 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 242 | if (val & (OTGSC_HADP | OTGSC_DP)) | ||
| 243 | otg_dbg("DataLine SRP Error\n"); | ||
| 244 | |||
| 245 | /* FIXME: VBus SRP */ | ||
| 246 | |||
| 247 | return 0; | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | /* stop SOF via bus_suspend */ | ||
| 252 | static void langwell_otg_loc_sof(int on) | ||
| 253 | { | ||
| 254 | struct usb_hcd *hcd; | ||
| 255 | int err; | ||
| 256 | |||
| 257 | otg_dbg("loc_sof -> %d\n", on); | ||
| 258 | |||
| 259 | hcd = bus_to_hcd(the_transceiver->otg.host); | ||
| 260 | if (on) | ||
| 261 | err = hcd->driver->bus_resume(hcd); | ||
| 262 | else | ||
| 263 | err = hcd->driver->bus_suspend(hcd); | ||
| 264 | |||
| 265 | if (err) | ||
| 266 | otg_dbg("Failed to resume/suspend bus - %d\n", err); | ||
| 267 | } | ||
| 268 | |||
| 269 | static void langwell_otg_phy_low_power(int on) | ||
| 270 | { | ||
| 271 | u32 val; | ||
| 272 | |||
| 273 | otg_dbg("phy low power mode-> %d\n", on); | ||
| 274 | |||
| 275 | val = readl(the_transceiver->regs + CI_HOSTPC1); | ||
| 276 | if (on) | ||
| 277 | writel(val | HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
| 278 | else | ||
| 279 | writel(val & ~HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* Enable/Disable OTG interrupt */ | ||
| 283 | static void langwell_otg_intr(int on) | ||
| 284 | { | ||
| 285 | u32 val; | ||
| 286 | |||
| 287 | otg_dbg("interrupt -> %d\n", on); | ||
| 288 | |||
| 289 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 290 | if (on) { | ||
| 291 | val = val | (OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
| 292 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
| 293 | } else { | ||
| 294 | val = val & ~(OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
| 295 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | /* set HAAR: Hardware Assist Auto-Reset */ | ||
| 300 | static void langwell_otg_HAAR(int on) | ||
| 301 | { | ||
| 302 | u32 val; | ||
| 303 | |||
| 304 | otg_dbg("HAAR -> %d\n", on); | ||
| 305 | |||
| 306 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 307 | if (on) | ||
| 308 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, | ||
| 309 | the_transceiver->regs + CI_OTGSC); | ||
| 310 | else | ||
| 311 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, | ||
| 312 | the_transceiver->regs + CI_OTGSC); | ||
| 313 | } | ||
| 314 | |||
| 315 | /* set HABA: Hardware Assist B-Disconnect to A-Connect */ | ||
| 316 | static void langwell_otg_HABA(int on) | ||
| 317 | { | ||
| 318 | u32 val; | ||
| 319 | |||
| 320 | otg_dbg("HABA -> %d\n", on); | ||
| 321 | |||
| 322 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
| 323 | if (on) | ||
| 324 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, | ||
| 325 | the_transceiver->regs + CI_OTGSC); | ||
| 326 | else | ||
| 327 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, | ||
| 328 | the_transceiver->regs + CI_OTGSC); | ||
| 329 | } | ||
| 330 | |||
| 331 | static int langwell_otg_check_se0_srp(int on) | ||
| 332 | { | ||
| 333 | u32 val; | ||
| 334 | |||
| 335 | int delay_time = TB_SE0_SRP * 10; /* step is 100us */ | ||
| 336 | |||
| 337 | otg_dbg("check_se0_srp -> \n"); | ||
| 338 | |||
| 339 | do { | ||
| 340 | udelay(100); | ||
| 341 | if (!delay_time--) | ||
| 342 | break; | ||
| 343 | val = readl(the_transceiver->regs + CI_PORTSC1); | ||
| 344 | val &= PORTSC_LS; | ||
| 345 | } while (!val); | ||
| 346 | |||
| 347 | otg_dbg("check_se0_srp <- \n"); | ||
| 348 | return val; | ||
| 349 | } | ||
| 350 | |||
| 351 | /* The timeout callback function to set time out bit */ | ||
| 352 | static void set_tmout(unsigned long indicator) | ||
| 353 | { | ||
| 354 | *(int *)indicator = 1; | ||
| 355 | } | ||
| 356 | |||
| 357 | void langwell_otg_nsf_msg(unsigned long indicator) | ||
| 358 | { | ||
| 359 | switch (indicator) { | ||
| 360 | case 2: | ||
| 361 | case 4: | ||
| 362 | case 6: | ||
| 363 | case 7: | ||
| 364 | printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n", | ||
| 365 | indicator); | ||
| 366 | break; | ||
| 367 | case 3: | ||
| 368 | printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n", | ||
| 369 | indicator); | ||
| 370 | break; | ||
| 371 | default: | ||
| 372 | printk(KERN_ERR "Do not have this kind of NSF\n"); | ||
| 373 | break; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | /* Initialize timers */ | ||
| 378 | static void langwell_otg_init_timers(struct otg_hsm *hsm) | ||
| 379 | { | ||
| 380 | /* HSM used timers */ | ||
| 381 | a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, | ||
| 382 | (unsigned long)&hsm->a_wait_vrise_tmout); | ||
| 383 | a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, | ||
| 384 | (unsigned long)&hsm->a_wait_bcon_tmout); | ||
| 385 | a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, | ||
| 386 | (unsigned long)&hsm->a_aidl_bdis_tmout); | ||
| 387 | b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, | ||
| 388 | (unsigned long)&hsm->b_ase0_brst_tmout); | ||
| 389 | b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, | ||
| 390 | (unsigned long)&hsm->b_se0_srp); | ||
| 391 | b_srp_res_tmr = otg_timer_initializer(&set_tmout, TB_SRP_RES, | ||
| 392 | (unsigned long)&hsm->b_srp_res_tmout); | ||
| 393 | b_bus_suspend_tmr = otg_timer_initializer(&set_tmout, TB_BUS_SUSPEND, | ||
| 394 | (unsigned long)&hsm->b_bus_suspend_tmout); | ||
| 395 | } | ||
| 396 | |||
| 397 | /* Free timers */ | ||
| 398 | static void langwell_otg_free_timers(void) | ||
| 399 | { | ||
| 400 | kfree(a_wait_vrise_tmr); | ||
| 401 | kfree(a_wait_bcon_tmr); | ||
| 402 | kfree(a_aidl_bdis_tmr); | ||
| 403 | kfree(b_ase0_brst_tmr); | ||
| 404 | kfree(b_se0_srp_tmr); | ||
| 405 | kfree(b_srp_res_tmr); | ||
| 406 | kfree(b_bus_suspend_tmr); | ||
| 407 | } | ||
| 408 | |||
| 409 | /* Add timer to timer list */ | ||
| 410 | static void langwell_otg_add_timer(void *gtimer) | ||
| 411 | { | ||
| 412 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
| 413 | struct langwell_otg_timer *tmp_timer; | ||
| 414 | u32 val32; | ||
| 415 | |||
| 416 | /* Check if the timer is already in the active list, | ||
| 417 | * if so update timer count | ||
| 418 | */ | ||
| 419 | list_for_each_entry(tmp_timer, &active_timers, list) | ||
| 420 | if (tmp_timer == timer) { | ||
| 421 | timer->count = timer->expires; | ||
| 422 | return; | ||
| 423 | } | ||
| 424 | timer->count = timer->expires; | ||
| 425 | |||
| 426 | if (list_empty(&active_timers)) { | ||
| 427 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
| 428 | writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
| 429 | } | ||
| 430 | |||
| 431 | list_add_tail(&timer->list, &active_timers); | ||
| 432 | } | ||
| 433 | |||
| 434 | /* Remove timer from the timer list; clear timeout status */ | ||
| 435 | static void langwell_otg_del_timer(void *gtimer) | ||
| 436 | { | ||
| 437 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
| 438 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
| 439 | u32 val32; | ||
| 440 | |||
| 441 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) | ||
| 442 | if (tmp_timer == timer) | ||
| 443 | list_del(&timer->list); | ||
| 444 | |||
| 445 | if (list_empty(&active_timers)) { | ||
| 446 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
| 447 | writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | /* Reduce timer count by 1, and find timeout conditions.*/ | ||
| 452 | static int langwell_otg_tick_timer(u32 *int_sts) | ||
| 453 | { | ||
| 454 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
| 455 | int expired = 0; | ||
| 456 | |||
| 457 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { | ||
| 458 | tmp_timer->count--; | ||
| 459 | /* check if timer expires */ | ||
| 460 | if (!tmp_timer->count) { | ||
| 461 | list_del(&tmp_timer->list); | ||
| 462 | tmp_timer->function(tmp_timer->data); | ||
| 463 | expired = 1; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | if (list_empty(&active_timers)) { | ||
| 468 | otg_dbg("tick timer: disable 1ms int\n"); | ||
| 469 | *int_sts = *int_sts & ~OTGSC_1MSE; | ||
| 470 | } | ||
| 471 | return expired; | ||
| 472 | } | ||
| 473 | |||
| 474 | static void reset_otg(void) | ||
| 475 | { | ||
| 476 | u32 val; | ||
| 477 | int delay_time = 1000; | ||
| 478 | |||
| 479 | otg_dbg("reseting OTG controller ...\n"); | ||
| 480 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
| 481 | writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD); | ||
| 482 | do { | ||
| 483 | udelay(100); | ||
| 484 | if (!delay_time--) | ||
| 485 | otg_dbg("reset timeout\n"); | ||
| 486 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
| 487 | val &= USBCMD_RST; | ||
| 488 | } while (val != 0); | ||
| 489 | otg_dbg("reset done.\n"); | ||
| 490 | } | ||
| 491 | |||
| 492 | static void set_host_mode(void) | ||
| 493 | { | ||
| 494 | u32 val; | ||
| 495 | |||
| 496 | reset_otg(); | ||
| 497 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
| 498 | val = (val & (~USBMODE_CM)) | USBMODE_HOST; | ||
| 499 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
| 500 | } | ||
| 501 | |||
| 502 | static void set_client_mode(void) | ||
| 503 | { | ||
| 504 | u32 val; | ||
| 505 | |||
| 506 | reset_otg(); | ||
| 507 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
| 508 | val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; | ||
| 509 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
| 510 | } | ||
| 511 | |||
| 512 | static void init_hsm(void) | ||
| 513 | { | ||
| 514 | struct langwell_otg *langwell = the_transceiver; | ||
| 515 | u32 val32; | ||
| 516 | |||
| 517 | /* read OTGSC after reset */ | ||
| 518 | val32 = readl(langwell->regs + CI_OTGSC); | ||
| 519 | otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32); | ||
| 520 | |||
| 521 | /* set init state */ | ||
| 522 | if (val32 & OTGSC_ID) { | ||
| 523 | langwell->hsm.id = 1; | ||
| 524 | langwell->otg.default_a = 0; | ||
| 525 | set_client_mode(); | ||
| 526 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 527 | langwell_otg_drv_vbus(0); | ||
| 528 | } else { | ||
| 529 | langwell->hsm.id = 0; | ||
| 530 | langwell->otg.default_a = 1; | ||
| 531 | set_host_mode(); | ||
| 532 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 533 | } | ||
| 534 | |||
| 535 | /* set session indicator */ | ||
| 536 | if (val32 & OTGSC_BSE) | ||
| 537 | langwell->hsm.b_sess_end = 1; | ||
| 538 | if (val32 & OTGSC_BSV) | ||
| 539 | langwell->hsm.b_sess_vld = 1; | ||
| 540 | if (val32 & OTGSC_ASV) | ||
| 541 | langwell->hsm.a_sess_vld = 1; | ||
| 542 | if (val32 & OTGSC_AVV) | ||
| 543 | langwell->hsm.a_vbus_vld = 1; | ||
| 544 | |||
| 545 | /* defautly power the bus */ | ||
| 546 | langwell->hsm.a_bus_req = 1; | ||
| 547 | langwell->hsm.a_bus_drop = 0; | ||
| 548 | /* defautly don't request bus as B device */ | ||
| 549 | langwell->hsm.b_bus_req = 0; | ||
| 550 | /* no system error */ | ||
| 551 | langwell->hsm.a_clr_err = 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | static irqreturn_t otg_dummy_irq(int irq, void *_dev) | ||
| 555 | { | ||
| 556 | void __iomem *reg_base = _dev; | ||
| 557 | u32 val; | ||
| 558 | u32 int_mask = 0; | ||
| 559 | |||
| 560 | val = readl(reg_base + CI_USBMODE); | ||
| 561 | if ((val & USBMODE_CM) != USBMODE_DEVICE) | ||
| 562 | return IRQ_NONE; | ||
| 563 | |||
| 564 | val = readl(reg_base + CI_USBSTS); | ||
| 565 | int_mask = val & INTR_DUMMY_MASK; | ||
| 566 | |||
| 567 | if (int_mask == 0) | ||
| 568 | return IRQ_NONE; | ||
| 569 | |||
| 570 | /* clear hsm.b_conn here since host driver can't detect it | ||
| 571 | * otg_dummy_irq called means B-disconnect happened. | ||
| 572 | */ | ||
| 573 | if (the_transceiver->hsm.b_conn) { | ||
| 574 | the_transceiver->hsm.b_conn = 0; | ||
| 575 | if (spin_trylock(&the_transceiver->wq_lock)) { | ||
| 576 | queue_work(the_transceiver->qwork, | ||
| 577 | &the_transceiver->work); | ||
| 578 | spin_unlock(&the_transceiver->wq_lock); | ||
| 579 | } | ||
| 580 | } | ||
| 581 | /* Clear interrupts */ | ||
| 582 | writel(int_mask, reg_base + CI_USBSTS); | ||
| 583 | return IRQ_HANDLED; | ||
| 584 | } | ||
| 585 | |||
| 586 | static irqreturn_t otg_irq(int irq, void *_dev) | ||
| 587 | { | ||
| 588 | struct langwell_otg *langwell = _dev; | ||
| 589 | u32 int_sts, int_en; | ||
| 590 | u32 int_mask = 0; | ||
| 591 | int flag = 0; | ||
| 592 | |||
| 593 | int_sts = readl(langwell->regs + CI_OTGSC); | ||
| 594 | int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; | ||
| 595 | int_mask = int_sts & int_en; | ||
| 596 | if (int_mask == 0) | ||
| 597 | return IRQ_NONE; | ||
| 598 | |||
| 599 | if (int_mask & OTGSC_IDIS) { | ||
| 600 | otg_dbg("%s: id change int\n", __func__); | ||
| 601 | langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; | ||
| 602 | flag = 1; | ||
| 603 | } | ||
| 604 | if (int_mask & OTGSC_DPIS) { | ||
| 605 | otg_dbg("%s: data pulse int\n", __func__); | ||
| 606 | langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; | ||
| 607 | flag = 1; | ||
| 608 | } | ||
| 609 | if (int_mask & OTGSC_BSEIS) { | ||
| 610 | otg_dbg("%s: b session end int\n", __func__); | ||
| 611 | langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; | ||
| 612 | flag = 1; | ||
| 613 | } | ||
| 614 | if (int_mask & OTGSC_BSVIS) { | ||
| 615 | otg_dbg("%s: b session valid int\n", __func__); | ||
| 616 | langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; | ||
| 617 | flag = 1; | ||
| 618 | } | ||
| 619 | if (int_mask & OTGSC_ASVIS) { | ||
| 620 | otg_dbg("%s: a session valid int\n", __func__); | ||
| 621 | langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; | ||
| 622 | flag = 1; | ||
| 623 | } | ||
| 624 | if (int_mask & OTGSC_AVVIS) { | ||
| 625 | otg_dbg("%s: a vbus valid int\n", __func__); | ||
| 626 | langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; | ||
| 627 | flag = 1; | ||
| 628 | } | ||
| 629 | |||
| 630 | if (int_mask & OTGSC_1MSS) { | ||
| 631 | /* need to schedule otg_work if any timer is expired */ | ||
| 632 | if (langwell_otg_tick_timer(&int_sts)) | ||
| 633 | flag = 1; | ||
| 634 | } | ||
| 635 | |||
| 636 | writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, | ||
| 637 | langwell->regs + CI_OTGSC); | ||
| 638 | if (flag) | ||
| 639 | queue_work(langwell->qwork, &langwell->work); | ||
| 640 | |||
| 641 | return IRQ_HANDLED; | ||
| 642 | } | ||
| 643 | |||
| 644 | static void langwell_otg_work(struct work_struct *work) | ||
| 645 | { | ||
| 646 | struct langwell_otg *langwell = container_of(work, | ||
| 647 | struct langwell_otg, work); | ||
| 648 | int retval; | ||
| 649 | |||
| 650 | otg_dbg("%s: old state = %s\n", __func__, | ||
| 651 | state_string(langwell->otg.state)); | ||
| 652 | |||
| 653 | switch (langwell->otg.state) { | ||
| 654 | case OTG_STATE_UNDEFINED: | ||
| 655 | case OTG_STATE_B_IDLE: | ||
| 656 | if (!langwell->hsm.id) { | ||
| 657 | langwell_otg_del_timer(b_srp_res_tmr); | ||
| 658 | langwell->otg.default_a = 1; | ||
| 659 | langwell->hsm.a_srp_det = 0; | ||
| 660 | |||
| 661 | langwell_otg_chrg_vbus(0); | ||
| 662 | langwell_otg_drv_vbus(0); | ||
| 663 | |||
| 664 | set_host_mode(); | ||
| 665 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 666 | queue_work(langwell->qwork, &langwell->work); | ||
| 667 | } else if (langwell->hsm.b_srp_res_tmout) { | ||
| 668 | langwell->hsm.b_srp_res_tmout = 0; | ||
| 669 | langwell->hsm.b_bus_req = 0; | ||
| 670 | langwell_otg_nsf_msg(6); | ||
| 671 | } else if (langwell->hsm.b_sess_vld) { | ||
| 672 | langwell_otg_del_timer(b_srp_res_tmr); | ||
| 673 | langwell->hsm.b_sess_end = 0; | ||
| 674 | langwell->hsm.a_bus_suspend = 0; | ||
| 675 | |||
| 676 | langwell_otg_chrg_vbus(0); | ||
| 677 | if (langwell->client_ops) { | ||
| 678 | langwell->client_ops->resume(langwell->pdev); | ||
| 679 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
| 680 | } else | ||
| 681 | otg_dbg("client driver not loaded.\n"); | ||
| 682 | |||
| 683 | } else if (langwell->hsm.b_bus_req && | ||
| 684 | (langwell->hsm.b_sess_end)) { | ||
| 685 | /* workaround for b_se0_srp detection */ | ||
| 686 | retval = langwell_otg_check_se0_srp(0); | ||
| 687 | if (retval) { | ||
| 688 | langwell->hsm.b_bus_req = 0; | ||
| 689 | otg_dbg("LS is not SE0, try again later\n"); | ||
| 690 | } else { | ||
| 691 | /* Start SRP */ | ||
| 692 | langwell_otg_start_srp(&langwell->otg); | ||
| 693 | langwell_otg_add_timer(b_srp_res_tmr); | ||
| 694 | } | ||
| 695 | } | ||
| 696 | break; | ||
| 697 | case OTG_STATE_B_SRP_INIT: | ||
| 698 | if (!langwell->hsm.id) { | ||
| 699 | langwell->otg.default_a = 1; | ||
| 700 | langwell->hsm.a_srp_det = 0; | ||
| 701 | |||
| 702 | langwell_otg_drv_vbus(0); | ||
| 703 | langwell_otg_chrg_vbus(0); | ||
| 704 | |||
| 705 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 706 | queue_work(langwell->qwork, &langwell->work); | ||
| 707 | } else if (langwell->hsm.b_sess_vld) { | ||
| 708 | langwell_otg_chrg_vbus(0); | ||
| 709 | if (langwell->client_ops) { | ||
| 710 | langwell->client_ops->resume(langwell->pdev); | ||
| 711 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
| 712 | } else | ||
| 713 | otg_dbg("client driver not loaded.\n"); | ||
| 714 | } | ||
| 715 | break; | ||
| 716 | case OTG_STATE_B_PERIPHERAL: | ||
| 717 | if (!langwell->hsm.id) { | ||
| 718 | langwell->otg.default_a = 1; | ||
| 719 | langwell->hsm.a_srp_det = 0; | ||
| 720 | |||
| 721 | langwell_otg_drv_vbus(0); | ||
| 722 | langwell_otg_chrg_vbus(0); | ||
| 723 | set_host_mode(); | ||
| 724 | |||
| 725 | if (langwell->client_ops) { | ||
| 726 | langwell->client_ops->suspend(langwell->pdev, | ||
| 727 | PMSG_FREEZE); | ||
| 728 | } else | ||
| 729 | otg_dbg("client driver has been removed.\n"); | ||
| 730 | |||
| 731 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 732 | queue_work(langwell->qwork, &langwell->work); | ||
| 733 | } else if (!langwell->hsm.b_sess_vld) { | ||
| 734 | langwell->hsm.b_hnp_enable = 0; | ||
| 735 | |||
| 736 | if (langwell->client_ops) { | ||
| 737 | langwell->client_ops->suspend(langwell->pdev, | ||
| 738 | PMSG_FREEZE); | ||
| 739 | } else | ||
| 740 | otg_dbg("client driver has been removed.\n"); | ||
| 741 | |||
| 742 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 743 | } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable | ||
| 744 | && langwell->hsm.a_bus_suspend) { | ||
| 745 | |||
| 746 | if (langwell->client_ops) { | ||
| 747 | langwell->client_ops->suspend(langwell->pdev, | ||
| 748 | PMSG_FREEZE); | ||
| 749 | } else | ||
| 750 | otg_dbg("client driver has been removed.\n"); | ||
| 751 | |||
| 752 | langwell_otg_HAAR(1); | ||
| 753 | langwell->hsm.a_conn = 0; | ||
| 754 | |||
| 755 | if (langwell->host_ops) { | ||
| 756 | langwell->host_ops->probe(langwell->pdev, | ||
| 757 | langwell->host_ops->id_table); | ||
| 758 | langwell->otg.state = OTG_STATE_B_WAIT_ACON; | ||
| 759 | } else | ||
| 760 | otg_dbg("host driver not loaded.\n"); | ||
| 761 | |||
| 762 | langwell->hsm.a_bus_resume = 0; | ||
| 763 | langwell->hsm.b_ase0_brst_tmout = 0; | ||
| 764 | langwell_otg_add_timer(b_ase0_brst_tmr); | ||
| 765 | } | ||
| 766 | break; | ||
| 767 | |||
| 768 | case OTG_STATE_B_WAIT_ACON: | ||
| 769 | if (!langwell->hsm.id) { | ||
| 770 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
| 771 | langwell->otg.default_a = 1; | ||
| 772 | langwell->hsm.a_srp_det = 0; | ||
| 773 | |||
| 774 | langwell_otg_drv_vbus(0); | ||
| 775 | langwell_otg_chrg_vbus(0); | ||
| 776 | set_host_mode(); | ||
| 777 | |||
| 778 | langwell_otg_HAAR(0); | ||
| 779 | if (langwell->host_ops) | ||
| 780 | langwell->host_ops->remove(langwell->pdev); | ||
| 781 | else | ||
| 782 | otg_dbg("host driver has been removed.\n"); | ||
| 783 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 784 | queue_work(langwell->qwork, &langwell->work); | ||
| 785 | } else if (!langwell->hsm.b_sess_vld) { | ||
| 786 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
| 787 | langwell->hsm.b_hnp_enable = 0; | ||
| 788 | langwell->hsm.b_bus_req = 0; | ||
| 789 | langwell_otg_chrg_vbus(0); | ||
| 790 | langwell_otg_HAAR(0); | ||
| 791 | |||
| 792 | if (langwell->host_ops) | ||
| 793 | langwell->host_ops->remove(langwell->pdev); | ||
| 794 | else | ||
| 795 | otg_dbg("host driver has been removed.\n"); | ||
| 796 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 797 | } else if (langwell->hsm.a_conn) { | ||
| 798 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
| 799 | langwell_otg_HAAR(0); | ||
| 800 | langwell->otg.state = OTG_STATE_B_HOST; | ||
| 801 | queue_work(langwell->qwork, &langwell->work); | ||
| 802 | } else if (langwell->hsm.a_bus_resume || | ||
| 803 | langwell->hsm.b_ase0_brst_tmout) { | ||
| 804 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
| 805 | langwell_otg_HAAR(0); | ||
| 806 | langwell_otg_nsf_msg(7); | ||
| 807 | |||
| 808 | if (langwell->host_ops) | ||
| 809 | langwell->host_ops->remove(langwell->pdev); | ||
| 810 | else | ||
| 811 | otg_dbg("host driver has been removed.\n"); | ||
| 812 | |||
| 813 | langwell->hsm.a_bus_suspend = 0; | ||
| 814 | langwell->hsm.b_bus_req = 0; | ||
| 815 | |||
| 816 | if (langwell->client_ops) | ||
| 817 | langwell->client_ops->resume(langwell->pdev); | ||
| 818 | else | ||
| 819 | otg_dbg("client driver not loaded.\n"); | ||
| 820 | |||
| 821 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
| 822 | } | ||
| 823 | break; | ||
| 824 | |||
| 825 | case OTG_STATE_B_HOST: | ||
| 826 | if (!langwell->hsm.id) { | ||
| 827 | langwell->otg.default_a = 1; | ||
| 828 | langwell->hsm.a_srp_det = 0; | ||
| 829 | |||
| 830 | langwell_otg_drv_vbus(0); | ||
| 831 | langwell_otg_chrg_vbus(0); | ||
| 832 | set_host_mode(); | ||
| 833 | if (langwell->host_ops) | ||
| 834 | langwell->host_ops->remove(langwell->pdev); | ||
| 835 | else | ||
| 836 | otg_dbg("host driver has been removed.\n"); | ||
| 837 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 838 | queue_work(langwell->qwork, &langwell->work); | ||
| 839 | } else if (!langwell->hsm.b_sess_vld) { | ||
| 840 | langwell->hsm.b_hnp_enable = 0; | ||
| 841 | langwell->hsm.b_bus_req = 0; | ||
| 842 | langwell_otg_chrg_vbus(0); | ||
| 843 | if (langwell->host_ops) | ||
| 844 | langwell->host_ops->remove(langwell->pdev); | ||
| 845 | else | ||
| 846 | otg_dbg("host driver has been removed.\n"); | ||
| 847 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 848 | } else if ((!langwell->hsm.b_bus_req) || | ||
| 849 | (!langwell->hsm.a_conn)) { | ||
| 850 | langwell->hsm.b_bus_req = 0; | ||
| 851 | langwell_otg_loc_sof(0); | ||
| 852 | if (langwell->host_ops) | ||
| 853 | langwell->host_ops->remove(langwell->pdev); | ||
| 854 | else | ||
| 855 | otg_dbg("host driver has been removed.\n"); | ||
| 856 | |||
| 857 | langwell->hsm.a_bus_suspend = 0; | ||
| 858 | |||
| 859 | if (langwell->client_ops) | ||
| 860 | langwell->client_ops->resume(langwell->pdev); | ||
| 861 | else | ||
| 862 | otg_dbg("client driver not loaded.\n"); | ||
| 863 | |||
| 864 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
| 865 | } | ||
| 866 | break; | ||
| 867 | |||
| 868 | case OTG_STATE_A_IDLE: | ||
| 869 | langwell->otg.default_a = 1; | ||
| 870 | if (langwell->hsm.id) { | ||
| 871 | langwell->otg.default_a = 0; | ||
| 872 | langwell->hsm.b_bus_req = 0; | ||
| 873 | langwell_otg_drv_vbus(0); | ||
| 874 | langwell_otg_chrg_vbus(0); | ||
| 875 | |||
| 876 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 877 | queue_work(langwell->qwork, &langwell->work); | ||
| 878 | } else if (langwell->hsm.a_sess_vld) { | ||
| 879 | langwell_otg_drv_vbus(1); | ||
| 880 | langwell->hsm.a_srp_det = 1; | ||
| 881 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
| 882 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
| 883 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
| 884 | queue_work(langwell->qwork, &langwell->work); | ||
| 885 | } else if (!langwell->hsm.a_bus_drop && | ||
| 886 | (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) { | ||
| 887 | langwell_otg_drv_vbus(1); | ||
| 888 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
| 889 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
| 890 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
| 891 | queue_work(langwell->qwork, &langwell->work); | ||
| 892 | } | ||
| 893 | break; | ||
| 894 | case OTG_STATE_A_WAIT_VRISE: | ||
| 895 | if (langwell->hsm.id) { | ||
| 896 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
| 897 | langwell->hsm.b_bus_req = 0; | ||
| 898 | langwell->otg.default_a = 0; | ||
| 899 | langwell_otg_drv_vbus(0); | ||
| 900 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 901 | } else if (langwell->hsm.a_vbus_vld) { | ||
| 902 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
| 903 | if (langwell->host_ops) | ||
| 904 | langwell->host_ops->probe(langwell->pdev, | ||
| 905 | langwell->host_ops->id_table); | ||
| 906 | else | ||
| 907 | otg_dbg("host driver not loaded.\n"); | ||
| 908 | langwell->hsm.b_conn = 0; | ||
| 909 | langwell->hsm.a_set_b_hnp_en = 0; | ||
| 910 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
| 911 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 912 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
| 913 | } else if (langwell->hsm.a_wait_vrise_tmout) { | ||
| 914 | if (langwell->hsm.a_vbus_vld) { | ||
| 915 | if (langwell->host_ops) | ||
| 916 | langwell->host_ops->probe( | ||
| 917 | langwell->pdev, | ||
| 918 | langwell->host_ops->id_table); | ||
| 919 | else | ||
| 920 | otg_dbg("host driver not loaded.\n"); | ||
| 921 | langwell->hsm.b_conn = 0; | ||
| 922 | langwell->hsm.a_set_b_hnp_en = 0; | ||
| 923 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
| 924 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 925 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
| 926 | } else { | ||
| 927 | langwell_otg_drv_vbus(0); | ||
| 928 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
| 929 | } | ||
| 930 | } | ||
| 931 | break; | ||
| 932 | case OTG_STATE_A_WAIT_BCON: | ||
| 933 | if (langwell->hsm.id) { | ||
| 934 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
| 935 | |||
| 936 | langwell->otg.default_a = 0; | ||
| 937 | langwell->hsm.b_bus_req = 0; | ||
| 938 | if (langwell->host_ops) | ||
| 939 | langwell->host_ops->remove(langwell->pdev); | ||
| 940 | else | ||
| 941 | otg_dbg("host driver has been removed.\n"); | ||
| 942 | langwell_otg_drv_vbus(0); | ||
| 943 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 944 | queue_work(langwell->qwork, &langwell->work); | ||
| 945 | } else if (!langwell->hsm.a_vbus_vld) { | ||
| 946 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
| 947 | |||
| 948 | if (langwell->host_ops) | ||
| 949 | langwell->host_ops->remove(langwell->pdev); | ||
| 950 | else | ||
| 951 | otg_dbg("host driver has been removed.\n"); | ||
| 952 | langwell_otg_drv_vbus(0); | ||
| 953 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
| 954 | } else if (langwell->hsm.a_bus_drop || | ||
| 955 | (langwell->hsm.a_wait_bcon_tmout && | ||
| 956 | !langwell->hsm.a_bus_req)) { | ||
| 957 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
| 958 | |||
| 959 | if (langwell->host_ops) | ||
| 960 | langwell->host_ops->remove(langwell->pdev); | ||
| 961 | else | ||
| 962 | otg_dbg("host driver has been removed.\n"); | ||
| 963 | langwell_otg_drv_vbus(0); | ||
| 964 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 965 | } else if (langwell->hsm.b_conn) { | ||
| 966 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
| 967 | |||
| 968 | langwell->hsm.a_suspend_req = 0; | ||
| 969 | langwell->otg.state = OTG_STATE_A_HOST; | ||
| 970 | if (!langwell->hsm.a_bus_req && | ||
| 971 | langwell->hsm.a_set_b_hnp_en) { | ||
| 972 | /* It is not safe enough to do a fast | ||
| 973 | * transistion from A_WAIT_BCON to | ||
| 974 | * A_SUSPEND */ | ||
| 975 | msleep(10000); | ||
| 976 | if (langwell->hsm.a_bus_req) | ||
| 977 | break; | ||
| 978 | |||
| 979 | if (request_irq(langwell->pdev->irq, | ||
| 980 | otg_dummy_irq, IRQF_SHARED, | ||
| 981 | driver_name, langwell->regs) != 0) { | ||
| 982 | otg_dbg("request interrupt %d fail\n", | ||
| 983 | langwell->pdev->irq); | ||
| 984 | } | ||
| 985 | |||
| 986 | langwell_otg_HABA(1); | ||
| 987 | langwell->hsm.b_bus_resume = 0; | ||
| 988 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
| 989 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
| 990 | |||
| 991 | langwell_otg_loc_sof(0); | ||
| 992 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
| 993 | } else if (!langwell->hsm.a_bus_req && | ||
| 994 | !langwell->hsm.a_set_b_hnp_en) { | ||
| 995 | struct pci_dev *pdev = langwell->pdev; | ||
| 996 | if (langwell->host_ops) | ||
| 997 | langwell->host_ops->remove(pdev); | ||
| 998 | else | ||
| 999 | otg_dbg("host driver removed.\n"); | ||
| 1000 | langwell_otg_drv_vbus(0); | ||
| 1001 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | break; | ||
| 1005 | case OTG_STATE_A_HOST: | ||
| 1006 | if (langwell->hsm.id) { | ||
| 1007 | langwell->otg.default_a = 0; | ||
| 1008 | langwell->hsm.b_bus_req = 0; | ||
| 1009 | if (langwell->host_ops) | ||
| 1010 | langwell->host_ops->remove(langwell->pdev); | ||
| 1011 | else | ||
| 1012 | otg_dbg("host driver has been removed.\n"); | ||
| 1013 | langwell_otg_drv_vbus(0); | ||
| 1014 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1015 | queue_work(langwell->qwork, &langwell->work); | ||
| 1016 | } else if (langwell->hsm.a_bus_drop || | ||
| 1017 | (!langwell->hsm.a_set_b_hnp_en && !langwell->hsm.a_bus_req)) { | ||
| 1018 | if (langwell->host_ops) | ||
| 1019 | langwell->host_ops->remove(langwell->pdev); | ||
| 1020 | else | ||
| 1021 | otg_dbg("host driver has been removed.\n"); | ||
| 1022 | langwell_otg_drv_vbus(0); | ||
| 1023 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1024 | } else if (!langwell->hsm.a_vbus_vld) { | ||
| 1025 | if (langwell->host_ops) | ||
| 1026 | langwell->host_ops->remove(langwell->pdev); | ||
| 1027 | else | ||
| 1028 | otg_dbg("host driver has been removed.\n"); | ||
| 1029 | langwell_otg_drv_vbus(0); | ||
| 1030 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
| 1031 | } else if (langwell->hsm.a_set_b_hnp_en | ||
| 1032 | && !langwell->hsm.a_bus_req) { | ||
| 1033 | /* Set HABA to enable hardware assistance to signal | ||
| 1034 | * A-connect after receiver B-disconnect. Hardware | ||
| 1035 | * will then set client mode and enable URE, SLE and | ||
| 1036 | * PCE after the assistance. otg_dummy_irq is used to | ||
| 1037 | * clean these ints when client driver is not resumed. | ||
| 1038 | */ | ||
| 1039 | if (request_irq(langwell->pdev->irq, | ||
| 1040 | otg_dummy_irq, IRQF_SHARED, driver_name, | ||
| 1041 | langwell->regs) != 0) { | ||
| 1042 | otg_dbg("request interrupt %d failed\n", | ||
| 1043 | langwell->pdev->irq); | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | /* set HABA */ | ||
| 1047 | langwell_otg_HABA(1); | ||
| 1048 | langwell->hsm.b_bus_resume = 0; | ||
| 1049 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
| 1050 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
| 1051 | langwell_otg_loc_sof(0); | ||
| 1052 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
| 1053 | } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) { | ||
| 1054 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
| 1055 | langwell->hsm.a_set_b_hnp_en = 0; | ||
| 1056 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 1057 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
| 1058 | } | ||
| 1059 | break; | ||
| 1060 | case OTG_STATE_A_SUSPEND: | ||
| 1061 | if (langwell->hsm.id) { | ||
| 1062 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1063 | langwell_otg_HABA(0); | ||
| 1064 | free_irq(langwell->pdev->irq, langwell->regs); | ||
| 1065 | langwell->otg.default_a = 0; | ||
| 1066 | langwell->hsm.b_bus_req = 0; | ||
| 1067 | if (langwell->host_ops) | ||
| 1068 | langwell->host_ops->remove(langwell->pdev); | ||
| 1069 | else | ||
| 1070 | otg_dbg("host driver has been removed.\n"); | ||
| 1071 | langwell_otg_drv_vbus(0); | ||
| 1072 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1073 | queue_work(langwell->qwork, &langwell->work); | ||
| 1074 | } else if (langwell->hsm.a_bus_req || | ||
| 1075 | langwell->hsm.b_bus_resume) { | ||
| 1076 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1077 | langwell_otg_HABA(0); | ||
| 1078 | free_irq(langwell->pdev->irq, langwell->regs); | ||
| 1079 | langwell->hsm.a_suspend_req = 0; | ||
| 1080 | langwell_otg_loc_sof(1); | ||
| 1081 | langwell->otg.state = OTG_STATE_A_HOST; | ||
| 1082 | } else if (langwell->hsm.a_aidl_bdis_tmout || | ||
| 1083 | langwell->hsm.a_bus_drop) { | ||
| 1084 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1085 | langwell_otg_HABA(0); | ||
| 1086 | free_irq(langwell->pdev->irq, langwell->regs); | ||
| 1087 | if (langwell->host_ops) | ||
| 1088 | langwell->host_ops->remove(langwell->pdev); | ||
| 1089 | else | ||
| 1090 | otg_dbg("host driver has been removed.\n"); | ||
| 1091 | langwell_otg_drv_vbus(0); | ||
| 1092 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1093 | } else if (!langwell->hsm.b_conn && | ||
| 1094 | langwell->hsm.a_set_b_hnp_en) { | ||
| 1095 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1096 | langwell_otg_HABA(0); | ||
| 1097 | free_irq(langwell->pdev->irq, langwell->regs); | ||
| 1098 | |||
| 1099 | if (langwell->host_ops) | ||
| 1100 | langwell->host_ops->remove(langwell->pdev); | ||
| 1101 | else | ||
| 1102 | otg_dbg("host driver has been removed.\n"); | ||
| 1103 | |||
| 1104 | langwell->hsm.b_bus_suspend = 0; | ||
| 1105 | langwell->hsm.b_bus_suspend_vld = 0; | ||
| 1106 | langwell->hsm.b_bus_suspend_tmout = 0; | ||
| 1107 | |||
| 1108 | /* msleep(200); */ | ||
| 1109 | if (langwell->client_ops) | ||
| 1110 | langwell->client_ops->resume(langwell->pdev); | ||
| 1111 | else | ||
| 1112 | otg_dbg("client driver not loaded.\n"); | ||
| 1113 | |||
| 1114 | langwell_otg_add_timer(b_bus_suspend_tmr); | ||
| 1115 | langwell->otg.state = OTG_STATE_A_PERIPHERAL; | ||
| 1116 | break; | ||
| 1117 | } else if (!langwell->hsm.a_vbus_vld) { | ||
| 1118 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1119 | langwell_otg_HABA(0); | ||
| 1120 | free_irq(langwell->pdev->irq, langwell->regs); | ||
| 1121 | if (langwell->host_ops) | ||
| 1122 | langwell->host_ops->remove(langwell->pdev); | ||
| 1123 | else | ||
| 1124 | otg_dbg("host driver has been removed.\n"); | ||
| 1125 | langwell_otg_drv_vbus(0); | ||
| 1126 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
| 1127 | } | ||
| 1128 | break; | ||
| 1129 | case OTG_STATE_A_PERIPHERAL: | ||
| 1130 | if (langwell->hsm.id) { | ||
| 1131 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
| 1132 | langwell->otg.default_a = 0; | ||
| 1133 | langwell->hsm.b_bus_req = 0; | ||
| 1134 | if (langwell->client_ops) | ||
| 1135 | langwell->client_ops->suspend(langwell->pdev, | ||
| 1136 | PMSG_FREEZE); | ||
| 1137 | else | ||
| 1138 | otg_dbg("client driver has been removed.\n"); | ||
| 1139 | langwell_otg_drv_vbus(0); | ||
| 1140 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1141 | queue_work(langwell->qwork, &langwell->work); | ||
| 1142 | } else if (!langwell->hsm.a_vbus_vld) { | ||
| 1143 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
| 1144 | if (langwell->client_ops) | ||
| 1145 | langwell->client_ops->suspend(langwell->pdev, | ||
| 1146 | PMSG_FREEZE); | ||
| 1147 | else | ||
| 1148 | otg_dbg("client driver has been removed.\n"); | ||
| 1149 | langwell_otg_drv_vbus(0); | ||
| 1150 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
| 1151 | } else if (langwell->hsm.a_bus_drop) { | ||
| 1152 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
| 1153 | if (langwell->client_ops) | ||
| 1154 | langwell->client_ops->suspend(langwell->pdev, | ||
| 1155 | PMSG_FREEZE); | ||
| 1156 | else | ||
| 1157 | otg_dbg("client driver has been removed.\n"); | ||
| 1158 | langwell_otg_drv_vbus(0); | ||
| 1159 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1160 | } else if (langwell->hsm.b_bus_suspend) { | ||
| 1161 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
| 1162 | if (langwell->client_ops) | ||
| 1163 | langwell->client_ops->suspend(langwell->pdev, | ||
| 1164 | PMSG_FREEZE); | ||
| 1165 | else | ||
| 1166 | otg_dbg("client driver has been removed.\n"); | ||
| 1167 | |||
| 1168 | if (langwell->host_ops) | ||
| 1169 | langwell->host_ops->probe(langwell->pdev, | ||
| 1170 | langwell->host_ops->id_table); | ||
| 1171 | else | ||
| 1172 | otg_dbg("host driver not loaded.\n"); | ||
| 1173 | langwell->hsm.a_set_b_hnp_en = 0; | ||
| 1174 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
| 1175 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 1176 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
| 1177 | } else if (langwell->hsm.b_bus_suspend_tmout) { | ||
| 1178 | u32 val; | ||
| 1179 | val = readl(langwell->regs + CI_PORTSC1); | ||
| 1180 | if (!(val & PORTSC_SUSP)) | ||
| 1181 | break; | ||
| 1182 | if (langwell->client_ops) | ||
| 1183 | langwell->client_ops->suspend(langwell->pdev, | ||
| 1184 | PMSG_FREEZE); | ||
| 1185 | else | ||
| 1186 | otg_dbg("client driver has been removed.\n"); | ||
| 1187 | if (langwell->host_ops) | ||
| 1188 | langwell->host_ops->probe(langwell->pdev, | ||
| 1189 | langwell->host_ops->id_table); | ||
| 1190 | else | ||
| 1191 | otg_dbg("host driver not loaded.\n"); | ||
| 1192 | langwell->hsm.a_set_b_hnp_en = 0; | ||
| 1193 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
| 1194 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 1195 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
| 1196 | } | ||
| 1197 | break; | ||
| 1198 | case OTG_STATE_A_VBUS_ERR: | ||
| 1199 | if (langwell->hsm.id) { | ||
| 1200 | langwell->otg.default_a = 0; | ||
| 1201 | langwell->hsm.a_clr_err = 0; | ||
| 1202 | langwell->hsm.a_srp_det = 0; | ||
| 1203 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1204 | queue_work(langwell->qwork, &langwell->work); | ||
| 1205 | } else if (langwell->hsm.a_clr_err) { | ||
| 1206 | langwell->hsm.a_clr_err = 0; | ||
| 1207 | langwell->hsm.a_srp_det = 0; | ||
| 1208 | reset_otg(); | ||
| 1209 | init_hsm(); | ||
| 1210 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
| 1211 | queue_work(langwell->qwork, &langwell->work); | ||
| 1212 | } | ||
| 1213 | break; | ||
| 1214 | case OTG_STATE_A_WAIT_VFALL: | ||
| 1215 | if (langwell->hsm.id) { | ||
| 1216 | langwell->otg.default_a = 0; | ||
| 1217 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1218 | queue_work(langwell->qwork, &langwell->work); | ||
| 1219 | } else if (langwell->hsm.a_bus_req) { | ||
| 1220 | langwell_otg_drv_vbus(1); | ||
| 1221 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
| 1222 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
| 1223 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
| 1224 | } else if (!langwell->hsm.a_sess_vld) { | ||
| 1225 | langwell->hsm.a_srp_det = 0; | ||
| 1226 | langwell_otg_drv_vbus(0); | ||
| 1227 | set_host_mode(); | ||
| 1228 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 1229 | } | ||
| 1230 | break; | ||
| 1231 | default: | ||
| 1232 | ; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | otg_dbg("%s: new state = %s\n", __func__, | ||
| 1236 | state_string(langwell->otg.state)); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | static ssize_t | ||
| 1240 | show_registers(struct device *_dev, struct device_attribute *attr, char *buf) | ||
| 1241 | { | ||
| 1242 | struct langwell_otg *langwell; | ||
| 1243 | char *next; | ||
| 1244 | unsigned size; | ||
| 1245 | unsigned t; | ||
| 1246 | |||
| 1247 | langwell = the_transceiver; | ||
| 1248 | next = buf; | ||
| 1249 | size = PAGE_SIZE; | ||
| 1250 | |||
| 1251 | t = scnprintf(next, size, | ||
| 1252 | "\n" | ||
| 1253 | "USBCMD = 0x%08x \n" | ||
| 1254 | "USBSTS = 0x%08x \n" | ||
| 1255 | "USBINTR = 0x%08x \n" | ||
| 1256 | "ASYNCLISTADDR = 0x%08x \n" | ||
| 1257 | "PORTSC1 = 0x%08x \n" | ||
| 1258 | "HOSTPC1 = 0x%08x \n" | ||
| 1259 | "OTGSC = 0x%08x \n" | ||
| 1260 | "USBMODE = 0x%08x \n", | ||
| 1261 | readl(langwell->regs + 0x30), | ||
| 1262 | readl(langwell->regs + 0x34), | ||
| 1263 | readl(langwell->regs + 0x38), | ||
| 1264 | readl(langwell->regs + 0x48), | ||
| 1265 | readl(langwell->regs + 0x74), | ||
| 1266 | readl(langwell->regs + 0xb4), | ||
| 1267 | readl(langwell->regs + 0xf4), | ||
| 1268 | readl(langwell->regs + 0xf8) | ||
| 1269 | ); | ||
| 1270 | size -= t; | ||
| 1271 | next += t; | ||
| 1272 | |||
| 1273 | return PAGE_SIZE - size; | ||
| 1274 | } | ||
| 1275 | static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); | ||
| 1276 | |||
| 1277 | static ssize_t | ||
| 1278 | show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) | ||
| 1279 | { | ||
| 1280 | struct langwell_otg *langwell; | ||
| 1281 | char *next; | ||
| 1282 | unsigned size; | ||
| 1283 | unsigned t; | ||
| 1284 | |||
| 1285 | langwell = the_transceiver; | ||
| 1286 | next = buf; | ||
| 1287 | size = PAGE_SIZE; | ||
| 1288 | |||
| 1289 | t = scnprintf(next, size, | ||
| 1290 | "\n" | ||
| 1291 | "current state = %s\n" | ||
| 1292 | "a_bus_resume = \t%d\n" | ||
| 1293 | "a_bus_suspend = \t%d\n" | ||
| 1294 | "a_conn = \t%d\n" | ||
| 1295 | "a_sess_vld = \t%d\n" | ||
| 1296 | "a_srp_det = \t%d\n" | ||
| 1297 | "a_vbus_vld = \t%d\n" | ||
| 1298 | "b_bus_resume = \t%d\n" | ||
| 1299 | "b_bus_suspend = \t%d\n" | ||
| 1300 | "b_conn = \t%d\n" | ||
| 1301 | "b_se0_srp = \t%d\n" | ||
| 1302 | "b_sess_end = \t%d\n" | ||
| 1303 | "b_sess_vld = \t%d\n" | ||
| 1304 | "id = \t%d\n" | ||
| 1305 | "a_set_b_hnp_en = \t%d\n" | ||
| 1306 | "b_srp_done = \t%d\n" | ||
| 1307 | "b_hnp_enable = \t%d\n" | ||
| 1308 | "a_wait_vrise_tmout = \t%d\n" | ||
| 1309 | "a_wait_bcon_tmout = \t%d\n" | ||
| 1310 | "a_aidl_bdis_tmout = \t%d\n" | ||
| 1311 | "b_ase0_brst_tmout = \t%d\n" | ||
| 1312 | "a_bus_drop = \t%d\n" | ||
| 1313 | "a_bus_req = \t%d\n" | ||
| 1314 | "a_clr_err = \t%d\n" | ||
| 1315 | "a_suspend_req = \t%d\n" | ||
| 1316 | "b_bus_req = \t%d\n" | ||
| 1317 | "b_bus_suspend_tmout = \t%d\n" | ||
| 1318 | "b_bus_suspend_vld = \t%d\n", | ||
| 1319 | state_string(langwell->otg.state), | ||
| 1320 | langwell->hsm.a_bus_resume, | ||
| 1321 | langwell->hsm.a_bus_suspend, | ||
| 1322 | langwell->hsm.a_conn, | ||
| 1323 | langwell->hsm.a_sess_vld, | ||
| 1324 | langwell->hsm.a_srp_det, | ||
| 1325 | langwell->hsm.a_vbus_vld, | ||
| 1326 | langwell->hsm.b_bus_resume, | ||
| 1327 | langwell->hsm.b_bus_suspend, | ||
| 1328 | langwell->hsm.b_conn, | ||
| 1329 | langwell->hsm.b_se0_srp, | ||
| 1330 | langwell->hsm.b_sess_end, | ||
| 1331 | langwell->hsm.b_sess_vld, | ||
| 1332 | langwell->hsm.id, | ||
| 1333 | langwell->hsm.a_set_b_hnp_en, | ||
| 1334 | langwell->hsm.b_srp_done, | ||
| 1335 | langwell->hsm.b_hnp_enable, | ||
| 1336 | langwell->hsm.a_wait_vrise_tmout, | ||
| 1337 | langwell->hsm.a_wait_bcon_tmout, | ||
| 1338 | langwell->hsm.a_aidl_bdis_tmout, | ||
| 1339 | langwell->hsm.b_ase0_brst_tmout, | ||
| 1340 | langwell->hsm.a_bus_drop, | ||
| 1341 | langwell->hsm.a_bus_req, | ||
| 1342 | langwell->hsm.a_clr_err, | ||
| 1343 | langwell->hsm.a_suspend_req, | ||
| 1344 | langwell->hsm.b_bus_req, | ||
| 1345 | langwell->hsm.b_bus_suspend_tmout, | ||
| 1346 | langwell->hsm.b_bus_suspend_vld | ||
| 1347 | ); | ||
| 1348 | size -= t; | ||
| 1349 | next += t; | ||
| 1350 | |||
| 1351 | return PAGE_SIZE - size; | ||
| 1352 | } | ||
| 1353 | static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); | ||
| 1354 | |||
| 1355 | static ssize_t | ||
| 1356 | get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1357 | { | ||
| 1358 | struct langwell_otg *langwell; | ||
| 1359 | char *next; | ||
| 1360 | unsigned size; | ||
| 1361 | unsigned t; | ||
| 1362 | |||
| 1363 | langwell = the_transceiver; | ||
| 1364 | next = buf; | ||
| 1365 | size = PAGE_SIZE; | ||
| 1366 | |||
| 1367 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req); | ||
| 1368 | size -= t; | ||
| 1369 | next += t; | ||
| 1370 | |||
| 1371 | return PAGE_SIZE - size; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | static ssize_t | ||
| 1375 | set_a_bus_req(struct device *dev, struct device_attribute *attr, | ||
| 1376 | const char *buf, size_t count) | ||
| 1377 | { | ||
| 1378 | struct langwell_otg *langwell; | ||
| 1379 | langwell = the_transceiver; | ||
| 1380 | if (!langwell->otg.default_a) | ||
| 1381 | return -1; | ||
| 1382 | if (count > 2) | ||
| 1383 | return -1; | ||
| 1384 | |||
| 1385 | if (buf[0] == '0') { | ||
| 1386 | langwell->hsm.a_bus_req = 0; | ||
| 1387 | otg_dbg("a_bus_req = 0\n"); | ||
| 1388 | } else if (buf[0] == '1') { | ||
| 1389 | /* If a_bus_drop is TRUE, a_bus_req can't be set */ | ||
| 1390 | if (langwell->hsm.a_bus_drop) | ||
| 1391 | return -1; | ||
| 1392 | langwell->hsm.a_bus_req = 1; | ||
| 1393 | otg_dbg("a_bus_req = 1\n"); | ||
| 1394 | } | ||
| 1395 | if (spin_trylock(&langwell->wq_lock)) { | ||
| 1396 | queue_work(langwell->qwork, &langwell->work); | ||
| 1397 | spin_unlock(&langwell->wq_lock); | ||
| 1398 | } | ||
| 1399 | return count; | ||
| 1400 | } | ||
| 1401 | static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req); | ||
| 1402 | |||
| 1403 | static ssize_t | ||
| 1404 | get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1405 | { | ||
| 1406 | struct langwell_otg *langwell; | ||
| 1407 | char *next; | ||
| 1408 | unsigned size; | ||
| 1409 | unsigned t; | ||
| 1410 | |||
| 1411 | langwell = the_transceiver; | ||
| 1412 | next = buf; | ||
| 1413 | size = PAGE_SIZE; | ||
| 1414 | |||
| 1415 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop); | ||
| 1416 | size -= t; | ||
| 1417 | next += t; | ||
| 1418 | |||
| 1419 | return PAGE_SIZE - size; | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | static ssize_t | ||
| 1423 | set_a_bus_drop(struct device *dev, struct device_attribute *attr, | ||
| 1424 | const char *buf, size_t count) | ||
| 1425 | { | ||
| 1426 | struct langwell_otg *langwell; | ||
| 1427 | langwell = the_transceiver; | ||
| 1428 | if (!langwell->otg.default_a) | ||
| 1429 | return -1; | ||
| 1430 | if (count > 2) | ||
| 1431 | return -1; | ||
| 1432 | |||
| 1433 | if (buf[0] == '0') { | ||
| 1434 | langwell->hsm.a_bus_drop = 0; | ||
| 1435 | otg_dbg("a_bus_drop = 0\n"); | ||
| 1436 | } else if (buf[0] == '1') { | ||
| 1437 | langwell->hsm.a_bus_drop = 1; | ||
| 1438 | langwell->hsm.a_bus_req = 0; | ||
| 1439 | otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n"); | ||
| 1440 | } | ||
| 1441 | if (spin_trylock(&langwell->wq_lock)) { | ||
| 1442 | queue_work(langwell->qwork, &langwell->work); | ||
| 1443 | spin_unlock(&langwell->wq_lock); | ||
| 1444 | } | ||
| 1445 | return count; | ||
| 1446 | } | ||
| 1447 | static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO, | ||
| 1448 | get_a_bus_drop, set_a_bus_drop); | ||
| 1449 | |||
| 1450 | static ssize_t | ||
| 1451 | get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 1452 | { | ||
| 1453 | struct langwell_otg *langwell; | ||
| 1454 | char *next; | ||
| 1455 | unsigned size; | ||
| 1456 | unsigned t; | ||
| 1457 | |||
| 1458 | langwell = the_transceiver; | ||
| 1459 | next = buf; | ||
| 1460 | size = PAGE_SIZE; | ||
| 1461 | |||
| 1462 | t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req); | ||
| 1463 | size -= t; | ||
| 1464 | next += t; | ||
| 1465 | |||
| 1466 | return PAGE_SIZE - size; | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | static ssize_t | ||
| 1470 | set_b_bus_req(struct device *dev, struct device_attribute *attr, | ||
| 1471 | const char *buf, size_t count) | ||
| 1472 | { | ||
| 1473 | struct langwell_otg *langwell; | ||
| 1474 | langwell = the_transceiver; | ||
| 1475 | |||
| 1476 | if (langwell->otg.default_a) | ||
| 1477 | return -1; | ||
| 1478 | |||
| 1479 | if (count > 2) | ||
| 1480 | return -1; | ||
| 1481 | |||
| 1482 | if (buf[0] == '0') { | ||
| 1483 | langwell->hsm.b_bus_req = 0; | ||
| 1484 | otg_dbg("b_bus_req = 0\n"); | ||
| 1485 | } else if (buf[0] == '1') { | ||
| 1486 | langwell->hsm.b_bus_req = 1; | ||
| 1487 | otg_dbg("b_bus_req = 1\n"); | ||
| 1488 | } | ||
| 1489 | if (spin_trylock(&langwell->wq_lock)) { | ||
| 1490 | queue_work(langwell->qwork, &langwell->work); | ||
| 1491 | spin_unlock(&langwell->wq_lock); | ||
| 1492 | } | ||
| 1493 | return count; | ||
| 1494 | } | ||
| 1495 | static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req); | ||
| 1496 | |||
| 1497 | static ssize_t | ||
| 1498 | set_a_clr_err(struct device *dev, struct device_attribute *attr, | ||
| 1499 | const char *buf, size_t count) | ||
| 1500 | { | ||
| 1501 | struct langwell_otg *langwell; | ||
| 1502 | langwell = the_transceiver; | ||
| 1503 | |||
| 1504 | if (!langwell->otg.default_a) | ||
| 1505 | return -1; | ||
| 1506 | if (count > 2) | ||
| 1507 | return -1; | ||
| 1508 | |||
| 1509 | if (buf[0] == '1') { | ||
| 1510 | langwell->hsm.a_clr_err = 1; | ||
| 1511 | otg_dbg("a_clr_err = 1\n"); | ||
| 1512 | } | ||
| 1513 | if (spin_trylock(&langwell->wq_lock)) { | ||
| 1514 | queue_work(langwell->qwork, &langwell->work); | ||
| 1515 | spin_unlock(&langwell->wq_lock); | ||
| 1516 | } | ||
| 1517 | return count; | ||
| 1518 | } | ||
| 1519 | static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err); | ||
| 1520 | |||
| 1521 | static struct attribute *inputs_attrs[] = { | ||
| 1522 | &dev_attr_a_bus_req.attr, | ||
| 1523 | &dev_attr_a_bus_drop.attr, | ||
| 1524 | &dev_attr_b_bus_req.attr, | ||
| 1525 | &dev_attr_a_clr_err.attr, | ||
| 1526 | NULL, | ||
| 1527 | }; | ||
| 1528 | |||
| 1529 | static struct attribute_group debug_dev_attr_group = { | ||
| 1530 | .name = "inputs", | ||
| 1531 | .attrs = inputs_attrs, | ||
| 1532 | }; | ||
| 1533 | |||
| 1534 | int langwell_register_host(struct pci_driver *host_driver) | ||
| 1535 | { | ||
| 1536 | int ret = 0; | ||
| 1537 | |||
| 1538 | the_transceiver->host_ops = host_driver; | ||
| 1539 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
| 1540 | otg_dbg("host controller driver is registered\n"); | ||
| 1541 | |||
| 1542 | return ret; | ||
| 1543 | } | ||
| 1544 | EXPORT_SYMBOL(langwell_register_host); | ||
| 1545 | |||
| 1546 | void langwell_unregister_host(struct pci_driver *host_driver) | ||
| 1547 | { | ||
| 1548 | if (the_transceiver->host_ops) | ||
| 1549 | the_transceiver->host_ops->remove(the_transceiver->pdev); | ||
| 1550 | the_transceiver->host_ops = NULL; | ||
| 1551 | the_transceiver->hsm.a_bus_drop = 1; | ||
| 1552 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
| 1553 | otg_dbg("host controller driver is unregistered\n"); | ||
| 1554 | } | ||
| 1555 | EXPORT_SYMBOL(langwell_unregister_host); | ||
| 1556 | |||
| 1557 | int langwell_register_peripheral(struct pci_driver *client_driver) | ||
| 1558 | { | ||
| 1559 | int ret = 0; | ||
| 1560 | |||
| 1561 | if (client_driver) | ||
| 1562 | ret = client_driver->probe(the_transceiver->pdev, | ||
| 1563 | client_driver->id_table); | ||
| 1564 | if (!ret) { | ||
| 1565 | the_transceiver->client_ops = client_driver; | ||
| 1566 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
| 1567 | otg_dbg("client controller driver is registered\n"); | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | return ret; | ||
| 1571 | } | ||
| 1572 | EXPORT_SYMBOL(langwell_register_peripheral); | ||
| 1573 | |||
| 1574 | void langwell_unregister_peripheral(struct pci_driver *client_driver) | ||
| 1575 | { | ||
| 1576 | if (the_transceiver->client_ops) | ||
| 1577 | the_transceiver->client_ops->remove(the_transceiver->pdev); | ||
| 1578 | the_transceiver->client_ops = NULL; | ||
| 1579 | the_transceiver->hsm.b_bus_req = 0; | ||
| 1580 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
| 1581 | otg_dbg("client controller driver is unregistered\n"); | ||
| 1582 | } | ||
| 1583 | EXPORT_SYMBOL(langwell_unregister_peripheral); | ||
| 1584 | |||
| 1585 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
| 1586 | const struct pci_device_id *id) | ||
| 1587 | { | ||
| 1588 | unsigned long resource, len; | ||
| 1589 | void __iomem *base = NULL; | ||
| 1590 | int retval; | ||
| 1591 | u32 val32; | ||
| 1592 | struct langwell_otg *langwell; | ||
| 1593 | char qname[] = "langwell_otg_queue"; | ||
| 1594 | |||
| 1595 | retval = 0; | ||
| 1596 | otg_dbg("\notg controller is detected.\n"); | ||
| 1597 | if (pci_enable_device(pdev) < 0) { | ||
| 1598 | retval = -ENODEV; | ||
| 1599 | goto done; | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | langwell = kzalloc(sizeof *langwell, GFP_KERNEL); | ||
| 1603 | if (langwell == NULL) { | ||
| 1604 | retval = -ENOMEM; | ||
| 1605 | goto done; | ||
| 1606 | } | ||
| 1607 | the_transceiver = langwell; | ||
| 1608 | |||
| 1609 | /* control register: BAR 0 */ | ||
| 1610 | resource = pci_resource_start(pdev, 0); | ||
| 1611 | len = pci_resource_len(pdev, 0); | ||
| 1612 | if (!request_mem_region(resource, len, driver_name)) { | ||
| 1613 | retval = -EBUSY; | ||
| 1614 | goto err; | ||
| 1615 | } | ||
| 1616 | langwell->region = 1; | ||
| 1617 | |||
| 1618 | base = ioremap_nocache(resource, len); | ||
| 1619 | if (base == NULL) { | ||
| 1620 | retval = -EFAULT; | ||
| 1621 | goto err; | ||
| 1622 | } | ||
| 1623 | langwell->regs = base; | ||
| 1624 | |||
| 1625 | if (!pdev->irq) { | ||
| 1626 | otg_dbg("No IRQ.\n"); | ||
| 1627 | retval = -ENODEV; | ||
| 1628 | goto err; | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | langwell->qwork = create_workqueue(qname); | ||
| 1632 | if (!langwell->qwork) { | ||
| 1633 | otg_dbg("cannot create workqueue %s\n", qname); | ||
| 1634 | retval = -ENOMEM; | ||
| 1635 | goto err; | ||
| 1636 | } | ||
| 1637 | INIT_WORK(&langwell->work, langwell_otg_work); | ||
| 1638 | |||
| 1639 | /* OTG common part */ | ||
| 1640 | langwell->pdev = pdev; | ||
| 1641 | langwell->otg.dev = &pdev->dev; | ||
| 1642 | langwell->otg.label = driver_name; | ||
| 1643 | langwell->otg.set_host = langwell_otg_set_host; | ||
| 1644 | langwell->otg.set_peripheral = langwell_otg_set_peripheral; | ||
| 1645 | langwell->otg.set_power = langwell_otg_set_power; | ||
| 1646 | langwell->otg.start_srp = langwell_otg_start_srp; | ||
| 1647 | langwell->otg.state = OTG_STATE_UNDEFINED; | ||
| 1648 | if (otg_set_transceiver(&langwell->otg)) { | ||
| 1649 | otg_dbg("can't set transceiver\n"); | ||
| 1650 | retval = -EBUSY; | ||
| 1651 | goto err; | ||
| 1652 | } | ||
| 1653 | |||
| 1654 | reset_otg(); | ||
| 1655 | init_hsm(); | ||
| 1656 | |||
| 1657 | spin_lock_init(&langwell->lock); | ||
| 1658 | spin_lock_init(&langwell->wq_lock); | ||
| 1659 | INIT_LIST_HEAD(&active_timers); | ||
| 1660 | langwell_otg_init_timers(&langwell->hsm); | ||
| 1661 | |||
| 1662 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
| 1663 | driver_name, langwell) != 0) { | ||
| 1664 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
| 1665 | retval = -EBUSY; | ||
| 1666 | goto err; | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | /* enable OTGSC int */ | ||
| 1670 | val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | | ||
| 1671 | OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; | ||
| 1672 | writel(val32, langwell->regs + CI_OTGSC); | ||
| 1673 | |||
| 1674 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
| 1675 | if (retval < 0) { | ||
| 1676 | otg_dbg("Can't register sysfs attribute: %d\n", retval); | ||
| 1677 | goto err; | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | retval = device_create_file(&pdev->dev, &dev_attr_hsm); | ||
| 1681 | if (retval < 0) { | ||
| 1682 | otg_dbg("Can't hsm sysfs attribute: %d\n", retval); | ||
| 1683 | goto err; | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
| 1687 | if (retval < 0) { | ||
| 1688 | otg_dbg("Can't register sysfs attr group: %d\n", retval); | ||
| 1689 | goto err; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
| 1693 | queue_work(langwell->qwork, &langwell->work); | ||
| 1694 | |||
| 1695 | return 0; | ||
| 1696 | |||
| 1697 | err: | ||
| 1698 | if (the_transceiver) | ||
| 1699 | langwell_otg_remove(pdev); | ||
| 1700 | done: | ||
| 1701 | return retval; | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | static void langwell_otg_remove(struct pci_dev *pdev) | ||
| 1705 | { | ||
| 1706 | struct langwell_otg *langwell; | ||
| 1707 | |||
| 1708 | langwell = the_transceiver; | ||
| 1709 | |||
| 1710 | if (langwell->qwork) { | ||
| 1711 | flush_workqueue(langwell->qwork); | ||
| 1712 | destroy_workqueue(langwell->qwork); | ||
| 1713 | } | ||
| 1714 | langwell_otg_free_timers(); | ||
| 1715 | |||
| 1716 | /* disable OTGSC interrupt as OTGSC doesn't change in reset */ | ||
| 1717 | writel(0, langwell->regs + CI_OTGSC); | ||
| 1718 | |||
| 1719 | if (pdev->irq) | ||
| 1720 | free_irq(pdev->irq, langwell); | ||
| 1721 | if (langwell->regs) | ||
| 1722 | iounmap(langwell->regs); | ||
| 1723 | if (langwell->region) | ||
| 1724 | release_mem_region(pci_resource_start(pdev, 0), | ||
| 1725 | pci_resource_len(pdev, 0)); | ||
| 1726 | |||
| 1727 | otg_set_transceiver(NULL); | ||
| 1728 | pci_disable_device(pdev); | ||
| 1729 | sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
| 1730 | device_remove_file(&pdev->dev, &dev_attr_hsm); | ||
| 1731 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
| 1732 | kfree(langwell); | ||
| 1733 | langwell = NULL; | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | static void transceiver_suspend(struct pci_dev *pdev) | ||
| 1737 | { | ||
| 1738 | pci_save_state(pdev); | ||
| 1739 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 1740 | langwell_otg_phy_low_power(1); | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) | ||
| 1744 | { | ||
| 1745 | int ret = 0; | ||
| 1746 | struct langwell_otg *langwell; | ||
| 1747 | |||
| 1748 | langwell = the_transceiver; | ||
| 1749 | |||
| 1750 | /* Disbale OTG interrupts */ | ||
| 1751 | langwell_otg_intr(0); | ||
| 1752 | |||
| 1753 | if (pdev->irq) | ||
| 1754 | free_irq(pdev->irq, langwell); | ||
| 1755 | |||
| 1756 | /* Prevent more otg_work */ | ||
| 1757 | flush_workqueue(langwell->qwork); | ||
| 1758 | spin_lock(&langwell->wq_lock); | ||
| 1759 | |||
| 1760 | /* start actions */ | ||
| 1761 | switch (langwell->otg.state) { | ||
| 1762 | case OTG_STATE_A_IDLE: | ||
| 1763 | case OTG_STATE_B_IDLE: | ||
| 1764 | case OTG_STATE_A_WAIT_VFALL: | ||
| 1765 | case OTG_STATE_A_VBUS_ERR: | ||
| 1766 | transceiver_suspend(pdev); | ||
| 1767 | break; | ||
| 1768 | case OTG_STATE_A_WAIT_VRISE: | ||
| 1769 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
| 1770 | langwell->hsm.a_srp_det = 0; | ||
| 1771 | langwell_otg_drv_vbus(0); | ||
| 1772 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
| 1773 | transceiver_suspend(pdev); | ||
| 1774 | break; | ||
| 1775 | case OTG_STATE_A_WAIT_BCON: | ||
| 1776 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
| 1777 | if (langwell->host_ops) | ||
| 1778 | ret = langwell->host_ops->suspend(pdev, message); | ||
| 1779 | langwell_otg_drv_vbus(0); | ||
| 1780 | break; | ||
| 1781 | case OTG_STATE_A_HOST: | ||
| 1782 | if (langwell->host_ops) | ||
| 1783 | ret = langwell->host_ops->suspend(pdev, message); | ||
| 1784 | langwell_otg_drv_vbus(0); | ||
| 1785 | langwell_otg_phy_low_power(1); | ||
| 1786 | break; | ||
| 1787 | case OTG_STATE_A_SUSPEND: | ||
| 1788 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
| 1789 | langwell_otg_HABA(0); | ||
| 1790 | if (langwell->host_ops) | ||
| 1791 | langwell->host_ops->remove(pdev); | ||
| 1792 | else | ||
| 1793 | otg_dbg("host driver has been removed.\n"); | ||
| 1794 | langwell_otg_drv_vbus(0); | ||
| 1795 | transceiver_suspend(pdev); | ||
| 1796 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1797 | break; | ||
| 1798 | case OTG_STATE_A_PERIPHERAL: | ||
| 1799 | if (langwell->client_ops) | ||
| 1800 | ret = langwell->client_ops->suspend(pdev, message); | ||
| 1801 | else | ||
| 1802 | otg_dbg("client driver has been removed.\n"); | ||
| 1803 | langwell_otg_drv_vbus(0); | ||
| 1804 | transceiver_suspend(pdev); | ||
| 1805 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
| 1806 | break; | ||
| 1807 | case OTG_STATE_B_HOST: | ||
| 1808 | if (langwell->host_ops) | ||
| 1809 | langwell->host_ops->remove(pdev); | ||
| 1810 | else | ||
| 1811 | otg_dbg("host driver has been removed.\n"); | ||
| 1812 | langwell->hsm.b_bus_req = 0; | ||
| 1813 | transceiver_suspend(pdev); | ||
| 1814 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1815 | break; | ||
| 1816 | case OTG_STATE_B_PERIPHERAL: | ||
| 1817 | if (langwell->client_ops) | ||
| 1818 | ret = langwell->client_ops->suspend(pdev, message); | ||
| 1819 | else | ||
| 1820 | otg_dbg("client driver has been removed.\n"); | ||
| 1821 | break; | ||
| 1822 | case OTG_STATE_B_WAIT_ACON: | ||
| 1823 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
| 1824 | langwell_otg_HAAR(0); | ||
| 1825 | if (langwell->host_ops) | ||
| 1826 | langwell->host_ops->remove(pdev); | ||
| 1827 | else | ||
| 1828 | otg_dbg("host driver has been removed.\n"); | ||
| 1829 | langwell->hsm.b_bus_req = 0; | ||
| 1830 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
| 1831 | transceiver_suspend(pdev); | ||
| 1832 | break; | ||
| 1833 | default: | ||
| 1834 | otg_dbg("error state before suspend\n "); | ||
| 1835 | break; | ||
| 1836 | } | ||
| 1837 | spin_unlock(&langwell->wq_lock); | ||
| 1838 | |||
| 1839 | return ret; | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | static void transceiver_resume(struct pci_dev *pdev) | ||
| 1843 | { | ||
| 1844 | pci_restore_state(pdev); | ||
| 1845 | pci_set_power_state(pdev, PCI_D0); | ||
| 1846 | langwell_otg_phy_low_power(0); | ||
| 1847 | } | ||
| 1848 | |||
| 1849 | static int langwell_otg_resume(struct pci_dev *pdev) | ||
| 1850 | { | ||
| 1851 | int ret = 0; | ||
| 1852 | struct langwell_otg *langwell; | ||
| 1853 | |||
| 1854 | langwell = the_transceiver; | ||
| 1855 | |||
| 1856 | spin_lock(&langwell->wq_lock); | ||
| 1857 | |||
| 1858 | switch (langwell->otg.state) { | ||
| 1859 | case OTG_STATE_A_IDLE: | ||
| 1860 | case OTG_STATE_B_IDLE: | ||
| 1861 | case OTG_STATE_A_WAIT_VFALL: | ||
| 1862 | case OTG_STATE_A_VBUS_ERR: | ||
| 1863 | transceiver_resume(pdev); | ||
| 1864 | break; | ||
| 1865 | case OTG_STATE_A_WAIT_BCON: | ||
| 1866 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
| 1867 | langwell_otg_drv_vbus(1); | ||
| 1868 | if (langwell->host_ops) | ||
| 1869 | ret = langwell->host_ops->resume(pdev); | ||
| 1870 | break; | ||
| 1871 | case OTG_STATE_A_HOST: | ||
| 1872 | langwell_otg_drv_vbus(1); | ||
| 1873 | langwell_otg_phy_low_power(0); | ||
| 1874 | if (langwell->host_ops) | ||
| 1875 | ret = langwell->host_ops->resume(pdev); | ||
| 1876 | break; | ||
| 1877 | case OTG_STATE_B_PERIPHERAL: | ||
| 1878 | if (langwell->client_ops) | ||
| 1879 | ret = langwell->client_ops->resume(pdev); | ||
| 1880 | else | ||
| 1881 | otg_dbg("client driver not loaded.\n"); | ||
| 1882 | break; | ||
| 1883 | default: | ||
| 1884 | otg_dbg("error state before suspend\n "); | ||
| 1885 | break; | ||
| 1886 | } | ||
| 1887 | |||
| 1888 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
| 1889 | driver_name, the_transceiver) != 0) { | ||
| 1890 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
| 1891 | ret = -EBUSY; | ||
| 1892 | } | ||
| 1893 | |||
| 1894 | /* enable OTG interrupts */ | ||
| 1895 | langwell_otg_intr(1); | ||
| 1896 | |||
| 1897 | spin_unlock(&langwell->wq_lock); | ||
| 1898 | |||
| 1899 | queue_work(langwell->qwork, &langwell->work); | ||
| 1900 | |||
| 1901 | |||
| 1902 | return ret; | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | static int __init langwell_otg_init(void) | ||
| 1906 | { | ||
| 1907 | return pci_register_driver(&otg_pci_driver); | ||
| 1908 | } | ||
| 1909 | module_init(langwell_otg_init); | ||
| 1910 | |||
| 1911 | static void __exit langwell_otg_cleanup(void) | ||
| 1912 | { | ||
| 1913 | pci_unregister_driver(&otg_pci_driver); | ||
| 1914 | } | ||
| 1915 | module_exit(langwell_otg_cleanup); | ||
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 9ed5ea568679..af456b48985f 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
| @@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register); | |||
| 53 | void usb_nop_xceiv_unregister(void) | 53 | void usb_nop_xceiv_unregister(void) |
| 54 | { | 54 | { |
| 55 | platform_device_unregister(pd); | 55 | platform_device_unregister(pd); |
| 56 | pd = NULL; | ||
| 56 | } | 57 | } |
| 57 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); | 58 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); |
| 58 | 59 | ||
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 247b61bfb7f4..0e4f2e41ace5 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
| @@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options) | |||
| 169 | kfree(tty); | 169 | kfree(tty); |
| 170 | } | 170 | } |
| 171 | } | 171 | } |
| 172 | /* So we know not to kill the hardware on a hangup on this | 172 | /* Now that any required fake tty operations are completed restore |
| 173 | port. We have also bumped the use count by one so it won't go | 173 | * the tty port count */ |
| 174 | idle */ | 174 | --port->port.count; |
| 175 | /* The console is special in terms of closing the device so | ||
| 176 | * indicate this port is now acting as a system console. */ | ||
| 175 | port->console = 1; | 177 | port->console = 1; |
| 176 | retval = 0; | 178 | retval = 0; |
| 177 | 179 | ||
| @@ -204,7 +206,7 @@ static void usb_console_write(struct console *co, | |||
| 204 | 206 | ||
| 205 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); | 207 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); |
| 206 | 208 | ||
| 207 | if (!port->port.count) { | 209 | if (!port->console) { |
| 208 | dbg("%s - port not opened", __func__); | 210 | dbg("%s - port not opened", __func__); |
| 209 | return; | 211 | return; |
| 210 | } | 212 | } |
| @@ -300,8 +302,7 @@ void usb_serial_console_exit(void) | |||
| 300 | { | 302 | { |
| 301 | if (usbcons_info.port) { | 303 | if (usbcons_info.port) { |
| 302 | unregister_console(&usbcons); | 304 | unregister_console(&usbcons); |
| 303 | if (usbcons_info.port->port.count) | 305 | usbcons_info.port->console = 0; |
| 304 | usbcons_info.port->port.count--; | ||
| 305 | usbcons_info.port = NULL; | 306 | usbcons_info.port = NULL; |
| 306 | } | 307 | } |
| 307 | } | 308 | } |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2b9eeda62bfe..e9a40b820fd4 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = { | |||
| 67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
| 68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
| 69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ | 69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ |
| 70 | { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */ | ||
| 71 | { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ | ||
| 70 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 72 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
| 71 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 73 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
| 72 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 74 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9734085fd2fe..59adfe123110 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
| @@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb) | |||
| 1228 | /* precursor to disconnect so just go away */ | 1228 | /* precursor to disconnect so just go away */ |
| 1229 | return; | 1229 | return; |
| 1230 | case -EPIPE: | 1230 | case -EPIPE: |
| 1231 | usb_clear_halt(port->serial->dev, 0x81); | 1231 | /* Can't call usb_clear_halt while in_interrupt */ |
| 1232 | break; | 1232 | /* FALLS THROUGH */ |
| 1233 | default: | 1233 | default: |
| 1234 | /* something ugly is going on... */ | 1234 | /* something ugly is going on... */ |
| 1235 | dev_err(&urb->dev->dev, | 1235 | dev_err(&urb->dev->dev, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5a8ae274d258..60c64cc5be2a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -108,6 +108,7 @@ struct ftdi_sio_quirk { | |||
| 108 | 108 | ||
| 109 | static int ftdi_jtag_probe(struct usb_serial *serial); | 109 | static int ftdi_jtag_probe(struct usb_serial *serial); |
| 110 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | 110 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); |
| 111 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | ||
| 111 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | 112 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); |
| 112 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | 113 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); |
| 113 | 114 | ||
| @@ -119,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | |||
| 119 | .probe = ftdi_mtxorb_hack_setup, | 120 | .probe = ftdi_mtxorb_hack_setup, |
| 120 | }; | 121 | }; |
| 121 | 122 | ||
| 123 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { | ||
| 124 | .probe = ftdi_NDI_device_setup, | ||
| 125 | }; | ||
| 126 | |||
| 122 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 127 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
| 123 | .port_probe = ftdi_USB_UIRT_setup, | 128 | .port_probe = ftdi_USB_UIRT_setup, |
| 124 | }; | 129 | }; |
| @@ -192,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 192 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 197 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
| 193 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 198 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
| 194 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 199 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
| 200 | { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, | ||
| 195 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, | 201 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, |
| 196 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, | 202 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, |
| 197 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, | 203 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, |
| @@ -580,6 +586,9 @@ static struct usb_device_id id_table_combined [] = { | |||
| 580 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 586 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
| 581 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
| 582 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, |
| 589 | { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) }, | ||
| 590 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) }, | ||
| 591 | { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) }, | ||
| 583 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 592 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
| 584 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 593 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
| 585 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 594 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
| @@ -645,6 +654,16 @@ static struct usb_device_id id_table_combined [] = { | |||
| 645 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, | 654 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, |
| 646 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 655 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
| 647 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 656 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
| 657 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID), | ||
| 658 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
| 659 | { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID), | ||
| 660 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
| 661 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID), | ||
| 662 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
| 663 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID), | ||
| 664 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
| 665 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), | ||
| 666 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
| 648 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 667 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
| 649 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 668 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
| 650 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, | 669 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, |
| @@ -661,6 +680,8 @@ static struct usb_device_id id_table_combined [] = { | |||
| 661 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 680 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 662 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), | 681 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), |
| 663 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 682 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 683 | { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), | ||
| 684 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
| 664 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 685 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
| 665 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 686 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
| 666 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 687 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
| @@ -668,7 +689,6 @@ static struct usb_device_id id_table_combined [] = { | |||
| 668 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 689 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
| 669 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 690 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
| 670 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, | 691 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, |
| 671 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, | ||
| 672 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, | 692 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, |
| 673 | { USB_DEVICE(DE_VID, STB_PID) }, | 693 | { USB_DEVICE(DE_VID, STB_PID) }, |
| 674 | { USB_DEVICE(DE_VID, WHT_PID) }, | 694 | { USB_DEVICE(DE_VID, WHT_PID) }, |
| @@ -1024,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
| 1024 | case FT2232C: /* FT2232C chip */ | 1044 | case FT2232C: /* FT2232C chip */ |
| 1025 | case FT232RL: | 1045 | case FT232RL: |
| 1026 | if (baud <= 3000000) { | 1046 | if (baud <= 3000000) { |
| 1047 | __u16 product_id = le16_to_cpu( | ||
| 1048 | port->serial->dev->descriptor.idProduct); | ||
| 1049 | if (((FTDI_NDI_HUC_PID == product_id) || | ||
| 1050 | (FTDI_NDI_SPECTRA_SCU_PID == product_id) || | ||
| 1051 | (FTDI_NDI_FUTURE_2_PID == product_id) || | ||
| 1052 | (FTDI_NDI_FUTURE_3_PID == product_id) || | ||
| 1053 | (FTDI_NDI_AURORA_SCU_PID == product_id)) && | ||
| 1054 | (baud == 19200)) { | ||
| 1055 | baud = 1200000; | ||
| 1056 | } | ||
| 1027 | div_value = ftdi_232bm_baud_to_divisor(baud); | 1057 | div_value = ftdi_232bm_baud_to_divisor(baud); |
| 1028 | } else { | 1058 | } else { |
| 1029 | dbg("%s - Baud rate too high!", __func__); | 1059 | dbg("%s - Baud rate too high!", __func__); |
| @@ -1555,6 +1585,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |||
| 1555 | } /* ftdi_HE_TIRA1_setup */ | 1585 | } /* ftdi_HE_TIRA1_setup */ |
| 1556 | 1586 | ||
| 1557 | /* | 1587 | /* |
| 1588 | * Module parameter to control latency timer for NDI FTDI-based USB devices. | ||
| 1589 | * If this value is not set in modprobe.conf.local its value will be set to 1ms. | ||
| 1590 | */ | ||
| 1591 | static int ndi_latency_timer = 1; | ||
| 1592 | |||
| 1593 | /* Setup for the NDI FTDI-based USB devices, which requires hardwired | ||
| 1594 | * baudrate (19200 gets mapped to 1200000). | ||
| 1595 | * | ||
| 1596 | * Called from usbserial:serial_probe. | ||
| 1597 | */ | ||
| 1598 | static int ftdi_NDI_device_setup(struct usb_serial *serial) | ||
| 1599 | { | ||
| 1600 | struct usb_device *udev = serial->dev; | ||
| 1601 | int latency = ndi_latency_timer; | ||
| 1602 | int rv = 0; | ||
| 1603 | char buf[1]; | ||
| 1604 | |||
| 1605 | if (latency == 0) | ||
| 1606 | latency = 1; | ||
| 1607 | if (latency > 99) | ||
| 1608 | latency = 99; | ||
| 1609 | |||
| 1610 | dbg("%s setting NDI device latency to %d", __func__, latency); | ||
| 1611 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | ||
| 1612 | |||
| 1613 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
| 1614 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
| 1615 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
| 1616 | latency, 0, buf, 0, WDR_TIMEOUT); | ||
| 1617 | return 0; | ||
| 1618 | } | ||
| 1619 | |||
| 1620 | /* | ||
| 1558 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko | 1621 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko |
| 1559 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from | 1622 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from |
| 1560 | * userspace using openocd. | 1623 | * userspace using openocd. |
| @@ -2623,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" | |||
| 2623 | module_param(product, ushort, 0); | 2686 | module_param(product, ushort, 0); |
| 2624 | MODULE_PARM_DESC(product, "User specified product ID"); | 2687 | MODULE_PARM_DESC(product, "User specified product ID"); |
| 2625 | 2688 | ||
| 2689 | module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR); | ||
| 2690 | MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f1d440a728a3..c9fbd7415092 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -506,6 +506,7 @@ | |||
| 506 | * | 506 | * |
| 507 | * Armin Laeuger originally sent the PID for the UM 100 module. | 507 | * Armin Laeuger originally sent the PID for the UM 100 module. |
| 508 | */ | 508 | */ |
| 509 | #define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ | ||
| 509 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ | 510 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ |
| 510 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ | 511 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ |
| 511 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ | 512 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ |
| @@ -614,6 +615,9 @@ | |||
| 614 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | 615 | #define FTDI_CCSICDU20_0_PID 0xF9D0 |
| 615 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | 616 | #define FTDI_CCSICDU40_1_PID 0xF9D1 |
| 616 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | 617 | #define FTDI_CCSMACHX_2_PID 0xF9D2 |
| 618 | #define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 | ||
| 619 | #define FTDI_CCSICDU64_4_PID 0xF9D4 | ||
| 620 | #define FTDI_CCSPRIME8_5_PID 0xF9D5 | ||
| 617 | 621 | ||
| 618 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | 622 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ |
| 619 | #define INSIDE_ACCESSO 0xFAD0 | 623 | #define INSIDE_ACCESSO 0xFAD0 |
| @@ -736,6 +740,15 @@ | |||
| 736 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 740 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
| 737 | 741 | ||
| 738 | /* | 742 | /* |
| 743 | * NDI (www.ndigital.com) product ids | ||
| 744 | */ | ||
| 745 | #define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ | ||
| 746 | #define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ | ||
| 747 | #define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ | ||
| 748 | #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ | ||
| 749 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | ||
| 750 | |||
| 751 | /* | ||
| 739 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | 752 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) |
| 740 | */ | 753 | */ |
| 741 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | 754 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ |
| @@ -848,9 +861,6 @@ | |||
| 848 | #define TML_VID 0x1B91 /* Vendor ID */ | 861 | #define TML_VID 0x1B91 /* Vendor ID */ |
| 849 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | 862 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ |
| 850 | 863 | ||
| 851 | /* NDI Polaris System */ | ||
| 852 | #define FTDI_NDI_HUC_PID 0xDA70 | ||
| 853 | |||
| 854 | /* Propox devices */ | 864 | /* Propox devices */ |
| 855 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 865 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
| 856 | 866 | ||
| @@ -934,6 +944,8 @@ | |||
| 934 | #define MARVELL_VID 0x9e88 | 944 | #define MARVELL_VID 0x9e88 |
| 935 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f | 945 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f |
| 936 | 946 | ||
| 947 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||
| 948 | |||
| 937 | /* | 949 | /* |
| 938 | * BmRequestType: 1100 0000b | 950 | * BmRequestType: 1100 0000b |
| 939 | * bRequest: FTDI_E2_READ | 951 | * bRequest: FTDI_E2_READ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 575816e6ba37..98262dd552bb 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -206,6 +206,7 @@ static int option_resume(struct usb_serial *serial); | |||
| 206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
| 207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 |
| 208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | 208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 |
| 209 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 | ||
| 209 | 210 | ||
| 210 | /* FUTURE NOVATEL PRODUCTS */ | 211 | /* FUTURE NOVATEL PRODUCTS */ |
| 211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 212 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 |
| @@ -307,11 +308,20 @@ static int option_resume(struct usb_serial *serial); | |||
| 307 | #define DLINK_VENDOR_ID 0x1186 | 308 | #define DLINK_VENDOR_ID 0x1186 |
| 308 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 309 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
| 309 | 310 | ||
| 311 | #define QISDA_VENDOR_ID 0x1da5 | ||
| 312 | #define QISDA_PRODUCT_H21_4512 0x4512 | ||
| 313 | #define QISDA_PRODUCT_H21_4523 0x4523 | ||
| 314 | #define QISDA_PRODUCT_H20_4515 0x4515 | ||
| 315 | #define QISDA_PRODUCT_H20_4519 0x4519 | ||
| 316 | |||
| 310 | 317 | ||
| 311 | /* TOSHIBA PRODUCTS */ | 318 | /* TOSHIBA PRODUCTS */ |
| 312 | #define TOSHIBA_VENDOR_ID 0x0930 | 319 | #define TOSHIBA_VENDOR_ID 0x0930 |
| 313 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 | 320 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 |
| 314 | 321 | ||
| 322 | #define ALINK_VENDOR_ID 0x1e0e | ||
| 323 | #define ALINK_PRODUCT_3GU 0x9200 | ||
| 324 | |||
| 315 | static struct usb_device_id option_ids[] = { | 325 | static struct usb_device_id option_ids[] = { |
| 316 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 326 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 317 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 327 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = { | |||
| 430 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 440 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
| 431 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 441 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ |
| 432 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ | 442 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ |
| 443 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ | ||
| 433 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 444 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ |
| 434 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 445 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ |
| 435 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 446 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ |
| @@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = { | |||
| 529 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 540 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
| 530 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 541 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
| 531 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 542 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
| 532 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 543 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
| 544 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | ||
| 545 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | ||
| 546 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, | ||
| 533 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 547 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
| 548 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | ||
| 549 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | ||
| 534 | { } /* Terminating entry */ | 550 | { } /* Terminating entry */ |
| 535 | }; | 551 | }; |
| 536 | MODULE_DEVICE_TABLE(usb, option_ids); | 552 | MODULE_DEVICE_TABLE(usb, option_ids); |
| @@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 732 | memcpy(this_urb->transfer_buffer, buf, todo); | 748 | memcpy(this_urb->transfer_buffer, buf, todo); |
| 733 | this_urb->transfer_buffer_length = todo; | 749 | this_urb->transfer_buffer_length = todo; |
| 734 | 750 | ||
| 735 | this_urb->dev = port->serial->dev; | ||
| 736 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 751 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
| 737 | if (err) { | 752 | if (err) { |
| 738 | dbg("usb_submit_urb %p (write bulk) failed " | 753 | dbg("usb_submit_urb %p (write bulk) failed " |
| @@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb) | |||
| 860 | 875 | ||
| 861 | /* Resubmit urb so we continue receiving IRQ data */ | 876 | /* Resubmit urb so we continue receiving IRQ data */ |
| 862 | if (status != -ESHUTDOWN && status != -ENOENT) { | 877 | if (status != -ESHUTDOWN && status != -ENOENT) { |
| 863 | urb->dev = serial->dev; | ||
| 864 | err = usb_submit_urb(urb, GFP_ATOMIC); | 878 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 865 | if (err) | 879 | if (err) |
| 866 | dbg("%s: resubmit intr urb failed. (%d)", | 880 | dbg("%s: resubmit intr urb failed. (%d)", |
| @@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty, | |||
| 921 | 935 | ||
| 922 | dbg("%s", __func__); | 936 | dbg("%s", __func__); |
| 923 | 937 | ||
| 924 | /* Reset low level data toggle and start reading from endpoints */ | 938 | /* Start reading from the IN endpoint */ |
| 925 | for (i = 0; i < N_IN_URB; i++) { | 939 | for (i = 0; i < N_IN_URB; i++) { |
| 926 | urb = portdata->in_urbs[i]; | 940 | urb = portdata->in_urbs[i]; |
| 927 | if (!urb) | 941 | if (!urb) |
| 928 | continue; | 942 | continue; |
| 929 | if (urb->dev != serial->dev) { | ||
| 930 | dbg("%s: dev %p != %p", __func__, | ||
| 931 | urb->dev, serial->dev); | ||
| 932 | continue; | ||
| 933 | } | ||
| 934 | |||
| 935 | /* | ||
| 936 | * make sure endpoint data toggle is synchronized with the | ||
| 937 | * device | ||
| 938 | */ | ||
| 939 | usb_clear_halt(urb->dev, urb->pipe); | ||
| 940 | |||
| 941 | err = usb_submit_urb(urb, GFP_KERNEL); | 943 | err = usb_submit_urb(urb, GFP_KERNEL); |
| 942 | if (err) { | 944 | if (err) { |
| 943 | dbg("%s: submit urb %d failed (%d) %d", | 945 | dbg("%s: submit urb %d failed (%d) %d", |
| @@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty, | |||
| 946 | } | 948 | } |
| 947 | } | 949 | } |
| 948 | 950 | ||
| 949 | /* Reset low level data toggle on out endpoints */ | ||
| 950 | for (i = 0; i < N_OUT_URB; i++) { | ||
| 951 | urb = portdata->out_urbs[i]; | ||
| 952 | if (!urb) | ||
| 953 | continue; | ||
| 954 | urb->dev = serial->dev; | ||
| 955 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
| 956 | usb_pipeout(urb->pipe), 0); */ | ||
| 957 | } | ||
| 958 | |||
| 959 | option_send_setup(port); | 951 | option_send_setup(port); |
| 960 | 952 | ||
| 961 | return 0; | 953 | return 0; |
| @@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial) | |||
| 1218 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | 1210 | dbg("%s: No interrupt URB for port %d\n", __func__, i); |
| 1219 | continue; | 1211 | continue; |
| 1220 | } | 1212 | } |
| 1221 | port->interrupt_in_urb->dev = serial->dev; | ||
| 1222 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | 1213 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); |
| 1223 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | 1214 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); |
| 1224 | if (err < 0) { | 1215 | if (err < 0) { |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index efaf59c4f5d0..7d15bfa7c2db 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = { | |||
| 94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, | 94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, |
| 95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
| 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
| 97 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | ||
| 97 | { } /* Terminating entry */ | 98 | { } /* Terminating entry */ |
| 98 | }; | 99 | }; |
| 99 | 100 | ||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 1d7a22e3a9fd..12aac7d2462d 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
| @@ -122,3 +122,7 @@ | |||
| 122 | /* Hewlett-Packard LD220-HP POS Pole Display */ | 122 | /* Hewlett-Packard LD220-HP POS Pole Display */ |
| 123 | #define HP_VENDOR_ID 0x03f0 | 123 | #define HP_VENDOR_ID 0x03f0 |
| 124 | #define HP_LD220_PRODUCT_ID 0x3524 | 124 | #define HP_LD220_PRODUCT_ID 0x3524 |
| 125 | |||
| 126 | /* Cressi Edy (diving computer) PC interface */ | ||
| 127 | #define CRESSI_VENDOR_ID 0x04b8 | ||
| 128 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 032f7aeb40a4..f48d05e0acc1 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
| @@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { | |||
| 181 | }; | 181 | }; |
| 182 | 182 | ||
| 183 | static struct usb_device_id id_table [] = { | 183 | static struct usb_device_id id_table [] = { |
| 184 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
| 185 | { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ | ||
| 186 | { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ | ||
| 187 | |||
| 184 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 188 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
| 185 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 189 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
| 186 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 190 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
| 187 | { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */ | ||
| 188 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 191 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
| 189 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
| 190 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ | 192 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ |
| 193 | { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */ | ||
| 194 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
| 195 | { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */ | ||
| 191 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 196 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
| 192 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 197 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
| 198 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
| 193 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | 199 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ |
| 194 | /* Sierra Wireless C597 */ | 200 | /* Sierra Wireless C597 */ |
| 195 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, | 201 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, |
| 196 | /* Sierra Wireless Device */ | 202 | /* Sierra Wireless T598 */ |
| 197 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, | 203 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, |
| 198 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ | 204 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ |
| 199 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ | 205 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ |
| 200 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ | 206 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ |
| 207 | { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */ | ||
| 201 | 208 | ||
| 202 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 209 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
| 203 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
| 204 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 210 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
| 211 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
| 212 | { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */ | ||
| 213 | { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */ | ||
| 214 | { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */ | ||
| 205 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ | 215 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
| 206 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */ | 216 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ |
| 207 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ | 217 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ |
| 208 | { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ | 218 | { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ |
| 209 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 219 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
| 210 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ | 220 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ |
| 221 | { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */ | ||
| 211 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ | 222 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ |
| 212 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ | 223 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ |
| 224 | { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */ | ||
| 225 | { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */ | ||
| 226 | { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */ | ||
| 227 | { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */ | ||
| 213 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ | 228 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ |
| 214 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ | 229 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ |
| 215 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ | 230 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ |
| @@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = { | |||
| 227 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ | 242 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ |
| 228 | /* Sierra Wireless C885 */ | 243 | /* Sierra Wireless C885 */ |
| 229 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, | 244 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, |
| 230 | /* Sierra Wireless Device */ | 245 | /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ |
| 231 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, | 246 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, |
| 232 | /* Sierra Wireless Device */ | 247 | /* Sierra Wireless C22/C33 */ |
| 233 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, | 248 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, |
| 234 | /* Sierra Wireless Device */ | 249 | /* Sierra Wireless HSPA Non-Composite Device */ |
| 235 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, | 250 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, |
| 236 | 251 | { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ | |
| 237 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
| 238 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
| 239 | |||
| 240 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | 252 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ |
| 241 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 253 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
| 242 | }, | 254 | }, |
| @@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial) | |||
| 814 | return 0; | 826 | return 0; |
| 815 | } | 827 | } |
| 816 | 828 | ||
| 817 | static void sierra_disconnect(struct usb_serial *serial) | 829 | static void sierra_release(struct usb_serial *serial) |
| 818 | { | 830 | { |
| 819 | int i; | 831 | int i; |
| 820 | struct usb_serial_port *port; | 832 | struct usb_serial_port *port; |
| @@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial) | |||
| 830 | if (!portdata) | 842 | if (!portdata) |
| 831 | continue; | 843 | continue; |
| 832 | kfree(portdata); | 844 | kfree(portdata); |
| 833 | usb_set_serial_port_data(port, NULL); | ||
| 834 | } | 845 | } |
| 835 | } | 846 | } |
| 836 | 847 | ||
| @@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = { | |||
| 853 | .tiocmget = sierra_tiocmget, | 864 | .tiocmget = sierra_tiocmget, |
| 854 | .tiocmset = sierra_tiocmset, | 865 | .tiocmset = sierra_tiocmset, |
| 855 | .attach = sierra_startup, | 866 | .attach = sierra_startup, |
| 856 | .disconnect = sierra_disconnect, | 867 | .release = sierra_release, |
| 857 | .read_int_callback = sierra_instat_callback, | 868 | .read_int_callback = sierra_instat_callback, |
| 858 | }; | 869 | }; |
| 859 | 870 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 991d8232e376..14971a926990 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
| @@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { | |||
| 191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, | 191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, |
| 192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, | 192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, |
| 193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
| 194 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
| 195 | }; | 194 | }; |
| 196 | 195 | ||
| 197 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { | 196 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { |
| @@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe, | |||
| 1658 | u8 cs = 0; | 1657 | u8 cs = 0; |
| 1659 | int done; | 1658 | int done; |
| 1660 | struct ti_firmware_header *header; | 1659 | struct ti_firmware_header *header; |
| 1661 | int status; | 1660 | int status = 0; |
| 1662 | int len; | 1661 | int len; |
| 1663 | 1662 | ||
| 1664 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) | 1663 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0c39b55aeef4..bd7581b3a48a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -221,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
| 221 | tty->driver_data = port; | 221 | tty->driver_data = port; |
| 222 | tty_port_tty_set(&port->port, tty); | 222 | tty_port_tty_set(&port->port, tty); |
| 223 | 223 | ||
| 224 | if (port->port.count == 1) { | 224 | /* If the console is attached, the device is already open */ |
| 225 | if (port->port.count == 1 && !port->console) { | ||
| 225 | 226 | ||
| 226 | /* lock this module before we call it | 227 | /* lock this module before we call it |
| 227 | * this may fail, which means we must bail out, | 228 | * this may fail, which means we must bail out, |
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index d41cc0a970f7..773a5cd38c5a 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c | |||
| @@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us) | |||
| 118 | 118 | ||
| 119 | result = memcmp(buffer+8, "Option", 6); | 119 | result = memcmp(buffer+8, "Option", 6); |
| 120 | 120 | ||
| 121 | if (result != 0) | ||
| 122 | result = memcmp(buffer+8, "ZCOPTION", 8); | ||
| 123 | |||
| 121 | /* Read the CSW */ | 124 | /* Read the CSW */ |
| 122 | usb_stor_bulk_transfer_buf(us, | 125 | usb_stor_bulk_transfer_buf(us, |
| 123 | us->recv_bulk_pipe, | 126 | us->recv_bulk_pipe, |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 84929e914034..b1e3c2fbfe11 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
| @@ -888,8 +888,6 @@ struct usb_driver { | |||
| 888 | * struct usb_device_driver - identifies USB device driver to usbcore | 888 | * struct usb_device_driver - identifies USB device driver to usbcore |
| 889 | * @name: The driver name should be unique among USB drivers, | 889 | * @name: The driver name should be unique among USB drivers, |
| 890 | * and should normally be the same as the module name. | 890 | * and should normally be the same as the module name. |
| 891 | * @nodename: Callback to provide a naming hint for a possible | ||
| 892 | * device node to create. | ||
| 893 | * @probe: Called to see if the driver is willing to manage a particular | 891 | * @probe: Called to see if the driver is willing to manage a particular |
| 894 | * device. If it is, probe returns zero and uses dev_set_drvdata() | 892 | * device. If it is, probe returns zero and uses dev_set_drvdata() |
| 895 | * to associate driver-specific data with the device. If unwilling | 893 | * to associate driver-specific data with the device. If unwilling |
| @@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type; | |||
| 924 | /** | 922 | /** |
| 925 | * struct usb_class_driver - identifies a USB driver that wants to use the USB major number | 923 | * struct usb_class_driver - identifies a USB driver that wants to use the USB major number |
| 926 | * @name: the usb class device name for this driver. Will show up in sysfs. | 924 | * @name: the usb class device name for this driver. Will show up in sysfs. |
| 925 | * @nodename: Callback to provide a naming hint for a possible | ||
| 926 | * device node to create. | ||
| 927 | * @fops: pointer to the struct file_operations of this driver. | 927 | * @fops: pointer to the struct file_operations of this driver. |
| 928 | * @minor_base: the start of the minor range for this driver. | 928 | * @minor_base: the start of the minor range for this driver. |
| 929 | * | 929 | * |
| @@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *); | |||
| 1046 | * the device driver is saying that it provided this DMA address, | 1046 | * the device driver is saying that it provided this DMA address, |
| 1047 | * which the host controller driver should use in preference to the | 1047 | * which the host controller driver should use in preference to the |
| 1048 | * transfer_buffer. | 1048 | * transfer_buffer. |
| 1049 | * @sg: scatter gather buffer list | ||
| 1050 | * @num_sgs: number of entries in the sg list | ||
| 1049 | * @transfer_buffer_length: How big is transfer_buffer. The transfer may | 1051 | * @transfer_buffer_length: How big is transfer_buffer. The transfer may |
| 1050 | * be broken up into chunks according to the current maximum packet | 1052 | * be broken up into chunks according to the current maximum packet |
| 1051 | * size for the endpoint, which is a function of the configuration | 1053 | * size for the endpoint, which is a function of the configuration |
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h deleted file mode 100644 index e115ae6df1da..000000000000 --- a/include/linux/usb/langwell_otg.h +++ /dev/null | |||
| @@ -1,177 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Intel Langwell USB OTG transceiver driver | ||
| 3 | * Copyright (C) 2008, Intel Corporation. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along with | ||
| 15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __LANGWELL_OTG_H__ | ||
| 21 | #define __LANGWELL_OTG_H__ | ||
| 22 | |||
| 23 | /* notify transceiver driver about OTG events */ | ||
| 24 | extern void langwell_update_transceiver(void); | ||
| 25 | /* HCD register bus driver */ | ||
| 26 | extern int langwell_register_host(struct pci_driver *host_driver); | ||
| 27 | /* HCD unregister bus driver */ | ||
| 28 | extern void langwell_unregister_host(struct pci_driver *host_driver); | ||
| 29 | /* DCD register bus driver */ | ||
| 30 | extern int langwell_register_peripheral(struct pci_driver *client_driver); | ||
| 31 | /* DCD unregister bus driver */ | ||
| 32 | extern void langwell_unregister_peripheral(struct pci_driver *client_driver); | ||
| 33 | /* No silent failure, output warning message */ | ||
| 34 | extern void langwell_otg_nsf_msg(unsigned long message); | ||
| 35 | |||
| 36 | #define CI_USBCMD 0x30 | ||
| 37 | # define USBCMD_RST BIT(1) | ||
| 38 | # define USBCMD_RS BIT(0) | ||
| 39 | #define CI_USBSTS 0x34 | ||
| 40 | # define USBSTS_SLI BIT(8) | ||
| 41 | # define USBSTS_URI BIT(6) | ||
| 42 | # define USBSTS_PCI BIT(2) | ||
| 43 | #define CI_PORTSC1 0x74 | ||
| 44 | # define PORTSC_PP BIT(12) | ||
| 45 | # define PORTSC_LS (BIT(11) | BIT(10)) | ||
| 46 | # define PORTSC_SUSP BIT(7) | ||
| 47 | # define PORTSC_CCS BIT(0) | ||
| 48 | #define CI_HOSTPC1 0xb4 | ||
| 49 | # define HOSTPC1_PHCD BIT(22) | ||
| 50 | #define CI_OTGSC 0xf4 | ||
| 51 | # define OTGSC_DPIE BIT(30) | ||
| 52 | # define OTGSC_1MSE BIT(29) | ||
| 53 | # define OTGSC_BSEIE BIT(28) | ||
| 54 | # define OTGSC_BSVIE BIT(27) | ||
| 55 | # define OTGSC_ASVIE BIT(26) | ||
| 56 | # define OTGSC_AVVIE BIT(25) | ||
| 57 | # define OTGSC_IDIE BIT(24) | ||
| 58 | # define OTGSC_DPIS BIT(22) | ||
| 59 | # define OTGSC_1MSS BIT(21) | ||
| 60 | # define OTGSC_BSEIS BIT(20) | ||
| 61 | # define OTGSC_BSVIS BIT(19) | ||
| 62 | # define OTGSC_ASVIS BIT(18) | ||
| 63 | # define OTGSC_AVVIS BIT(17) | ||
| 64 | # define OTGSC_IDIS BIT(16) | ||
| 65 | # define OTGSC_DPS BIT(14) | ||
| 66 | # define OTGSC_1MST BIT(13) | ||
| 67 | # define OTGSC_BSE BIT(12) | ||
| 68 | # define OTGSC_BSV BIT(11) | ||
| 69 | # define OTGSC_ASV BIT(10) | ||
| 70 | # define OTGSC_AVV BIT(9) | ||
| 71 | # define OTGSC_ID BIT(8) | ||
| 72 | # define OTGSC_HABA BIT(7) | ||
| 73 | # define OTGSC_HADP BIT(6) | ||
| 74 | # define OTGSC_IDPU BIT(5) | ||
| 75 | # define OTGSC_DP BIT(4) | ||
| 76 | # define OTGSC_OT BIT(3) | ||
| 77 | # define OTGSC_HAAR BIT(2) | ||
| 78 | # define OTGSC_VC BIT(1) | ||
| 79 | # define OTGSC_VD BIT(0) | ||
| 80 | # define OTGSC_INTEN_MASK (0x7f << 24) | ||
| 81 | # define OTGSC_INTSTS_MASK (0x7f << 16) | ||
| 82 | #define CI_USBMODE 0xf8 | ||
| 83 | # define USBMODE_CM (BIT(1) | BIT(0)) | ||
| 84 | # define USBMODE_IDLE 0 | ||
| 85 | # define USBMODE_DEVICE 0x2 | ||
| 86 | # define USBMODE_HOST 0x3 | ||
| 87 | |||
| 88 | #define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI) | ||
| 89 | |||
| 90 | struct otg_hsm { | ||
| 91 | /* Input */ | ||
| 92 | int a_bus_resume; | ||
| 93 | int a_bus_suspend; | ||
| 94 | int a_conn; | ||
| 95 | int a_sess_vld; | ||
| 96 | int a_srp_det; | ||
| 97 | int a_vbus_vld; | ||
| 98 | int b_bus_resume; | ||
| 99 | int b_bus_suspend; | ||
| 100 | int b_conn; | ||
| 101 | int b_se0_srp; | ||
| 102 | int b_sess_end; | ||
| 103 | int b_sess_vld; | ||
| 104 | int id; | ||
| 105 | |||
| 106 | /* Internal variables */ | ||
| 107 | int a_set_b_hnp_en; | ||
| 108 | int b_srp_done; | ||
| 109 | int b_hnp_enable; | ||
| 110 | |||
| 111 | /* Timeout indicator for timers */ | ||
| 112 | int a_wait_vrise_tmout; | ||
| 113 | int a_wait_bcon_tmout; | ||
| 114 | int a_aidl_bdis_tmout; | ||
| 115 | int b_ase0_brst_tmout; | ||
| 116 | int b_bus_suspend_tmout; | ||
| 117 | int b_srp_res_tmout; | ||
| 118 | |||
| 119 | /* Informative variables */ | ||
| 120 | int a_bus_drop; | ||
| 121 | int a_bus_req; | ||
| 122 | int a_clr_err; | ||
| 123 | int a_suspend_req; | ||
| 124 | int b_bus_req; | ||
| 125 | |||
| 126 | /* Output */ | ||
| 127 | int drv_vbus; | ||
| 128 | int loc_conn; | ||
| 129 | int loc_sof; | ||
| 130 | |||
| 131 | /* Others */ | ||
| 132 | int b_bus_suspend_vld; | ||
| 133 | }; | ||
| 134 | |||
| 135 | #define TA_WAIT_VRISE 100 | ||
| 136 | #define TA_WAIT_BCON 30000 | ||
| 137 | #define TA_AIDL_BDIS 15000 | ||
| 138 | #define TB_ASE0_BRST 5000 | ||
| 139 | #define TB_SE0_SRP 2 | ||
| 140 | #define TB_SRP_RES 100 | ||
| 141 | #define TB_BUS_SUSPEND 500 | ||
| 142 | |||
| 143 | struct langwell_otg_timer { | ||
| 144 | unsigned long expires; /* Number of count increase to timeout */ | ||
| 145 | unsigned long count; /* Tick counter */ | ||
| 146 | void (*function)(unsigned long); /* Timeout function */ | ||
| 147 | unsigned long data; /* Data passed to function */ | ||
| 148 | struct list_head list; | ||
| 149 | }; | ||
| 150 | |||
| 151 | struct langwell_otg { | ||
| 152 | struct otg_transceiver otg; | ||
| 153 | struct otg_hsm hsm; | ||
| 154 | void __iomem *regs; | ||
| 155 | unsigned region; | ||
| 156 | struct pci_driver *host_ops; | ||
| 157 | struct pci_driver *client_ops; | ||
| 158 | struct pci_dev *pdev; | ||
| 159 | struct work_struct work; | ||
| 160 | struct workqueue_struct *qwork; | ||
| 161 | spinlock_t lock; | ||
| 162 | spinlock_t wq_lock; | ||
| 163 | }; | ||
| 164 | |||
| 165 | static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg) | ||
| 166 | { | ||
| 167 | return container_of(otg, struct langwell_otg, otg); | ||
| 168 | } | ||
| 169 | |||
| 170 | #ifdef DEBUG | ||
| 171 | #define otg_dbg(fmt, args...) \ | ||
| 172 | printk(KERN_DEBUG fmt , ## args) | ||
| 173 | #else | ||
| 174 | #define otg_dbg(fmt, args...) \ | ||
| 175 | do { } while (0) | ||
| 176 | #endif /* DEBUG */ | ||
| 177 | #endif /* __LANGWELL_OTG_H__ */ | ||
