X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fusb%2Fatm%2Fusbatm.c;h=11e9b15ca45a35fb7c37e84fef91e07c54b2b507;hb=2ed22bc294315d19aa1f0423b83d21a2d94c641b;hp=a38701c742c3209cb0599faf558099b51a0db452;hpb=b20e481ab595e9667c33e2393bdfe9a31870d11f;p=powerpc.git diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index a38701c742..11e9b15ca4 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -77,7 +77,6 @@ #include #include #include -#include #include #include #include @@ -254,7 +253,7 @@ static int usbatm_submit_urb(struct urb *urb) return ret; } -static void usbatm_complete(struct urb *urb, struct pt_regs *regs) +static void usbatm_complete(struct urb *urb) { struct usbatm_channel *channel = urb->context; unsigned long flags; @@ -274,6 +273,9 @@ static void usbatm_complete(struct urb *urb, struct pt_regs *regs) (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || urb->status != -EILSEQ )) { + if (urb->status == -ESHUTDOWN) + return; + if (printk_ratelimit()) atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", __func__, urb, urb->status); @@ -343,7 +345,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end); } - memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); + memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD); __skb_put(sarb, ATM_CELL_PAYLOAD); if (pti & 1) { @@ -370,7 +372,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char goto out; } - if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) { + if (crc32_be(~0, skb_tail_pointer(sarb) - pdu_length, pdu_length) != 0xc704dd7b) { atm_rldbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n", __func__, vcc); atomic_inc(&vcc->stats->rx_err); @@ -396,7 +398,9 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char goto out; /* atm_charge increments rx_drop */ } - memcpy(skb->data, sarb->tail - pdu_length, length); + skb_copy_to_linear_data(skb, + skb_tail_pointer(sarb) - pdu_length, + length); __skb_put(skb, length); vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u", @@ -484,7 +488,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance, ptr[4] = 0xec; ptr += ATM_CELL_HEADER; - memcpy(ptr, skb->data, data_len); + skb_copy_from_linear_data(skb, ptr, data_len); ptr += data_len; __skb_pull(skb, data_len); @@ -966,6 +970,14 @@ static int usbatm_atm_init(struct usbatm_data *instance) /* temp init ATM device, set to 128kbit */ atm_dev->link_rate = 128 * 1000 / 424; + ret = sysfs_create_link(&atm_dev->class_dev.kobj, + &instance->usb_intf->dev.kobj, "device"); + if (ret) { + atm_err(instance, "%s: sysfs_create_link failed: %d\n", + __func__, ret); + goto fail_sysfs; + } + if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); goto fail; @@ -984,6 +996,8 @@ static int usbatm_atm_init(struct usbatm_data *instance) return 0; fail: + sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); + fail_sysfs: instance->atm_dev = NULL; atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ return ret; @@ -1001,6 +1015,7 @@ static int usbatm_do_heavy_init(void *arg) daemonize(instance->driver->driver_name); allow_signal(SIGTERM); + instance->thread_pid = current->pid; complete(&instance->thread_started); @@ -1018,17 +1033,13 @@ static int usbatm_do_heavy_init(void *arg) static int usbatm_heavy_init(struct usbatm_data *instance) { - int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL); + int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_FS | CLONE_FILES); if (ret < 0) { usb_err(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret); return ret; } - mutex_lock(&instance->serialize); - instance->thread_pid = ret; - mutex_unlock(&instance->serialize); - wait_for_completion(&instance->thread_started); return 0; @@ -1319,8 +1330,10 @@ void usbatm_usb_disconnect(struct usb_interface *intf) kfree(instance->cell_buf); /* ATM finalize */ - if (instance->atm_dev) + if (instance->atm_dev) { + sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); atm_dev_deregister(instance->atm_dev); + } usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ }