static void rts51x_disconnect(struct usb_interface *intf) { struct rts51x_chip *chip = (struct rts51x_chip *)usb_get_intfdata(intf); RTS51X_DEBUGP("rts51x_disconnect() called\n"); quiesce_and_remove_host(chip); release_everything(chip); }
void our_disconnect(struct usb_interface *intf){ struct us_data *us = usb_get_intfdata(intf); //--------------------------- pr_info("23 disconnect\n"); US_DEBUGP("storage_disconnect() called\n"); quiesce_and_remove_host(us); release_everything(us); }
static void rtsx_remove(struct pci_dev *pci) { struct rtsx_dev *dev = pci_get_drvdata(pci); dev_info(&pci->dev, "rtsx_remove() called\n"); quiesce_and_remove_host(dev); release_everything(dev); }
static void __devexit rtsx_remove(struct pci_dev *pci) { struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); printk(KERN_INFO "rtsx_remove() called\n"); quiesce_and_remove_host(dev); release_everything(dev); pci_set_drvdata(pci, NULL); }
static int rtsx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct Scsi_Host *host; struct rtsx_dev *dev; int err = 0; struct task_struct *th; dev_dbg(&pci->dev, "Realtek PCI-E card reader detected\n"); err = pcim_enable_device(pci); if (err < 0) { dev_err(&pci->dev, "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { dev_err(&pci->dev, "PCI request regions for %s failed!\n", CR_DRIVER_NAME); return err; } /* * Ask the SCSI layer to allocate a host structure, with extra * space at the end for our private rtsx_dev structure. */ host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); if (!host) { dev_err(&pci->dev, "Unable to allocate the scsi host\n"); return -ENOMEM; } dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL); if (!dev->chip) { err = -ENOMEM; goto errout; } spin_lock_init(&dev->reg_lock); mutex_init(&(dev->dev_mutex)); init_completion(&dev->cmnd_ready); init_completion(&dev->control_exit); init_completion(&dev->polling_exit); init_completion(&(dev->notify)); init_completion(&dev->scanning_done); init_waitqueue_head(&dev->delay_wait); dev->pci = pci; dev->irq = -1; dev_info(&pci->dev, "Resource length: 0x%x\n", (unsigned int)pci_resource_len(pci, 0)); dev->addr = pci_resource_start(pci, 0); dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); if (!dev->remap_addr) { dev_err(&pci->dev, "ioremap error\n"); err = -ENXIO; goto errout; } /* * Using "unsigned long" cast here to eliminate gcc warning in * 64-bit system */ dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dmam_alloc_coherent(&pci->dev, RTSX_RESV_BUF_LEN, &dev->rtsx_resv_buf_addr, GFP_KERNEL); if (!dev->rtsx_resv_buf) { dev_err(&pci->dev, "alloc dma buffer fail\n"); err = -ENXIO; goto errout; } dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; dev->chip->rtsx = dev; rtsx_init_options(dev->chip); dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); if (dev->chip->msi_en) { if (pci_enable_msi(pci) < 0) dev->chip->msi_en = 0; } if (rtsx_acquire_irq(dev) < 0) { err = -EBUSY; goto errout; } pci_set_master(pci); synchronize_irq(dev->irq); rtsx_init_chip(dev->chip); /* * set the supported max_lun and max_id for the scsi host * NOTE: the minimal value of max_id is 1 */ host->max_id = 1; host->max_lun = dev->chip->max_lun; /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start control thread\n"); err = PTR_ERR(th); goto errout; } dev->ctl_thread = th; err = scsi_add_host(host, &pci->dev); if (err) { dev_err(&pci->dev, "Unable to add the scsi host\n"); goto errout; } /* Start up the thread for delayed SCSI-device scanning */ th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); complete(&dev->scanning_done); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* Start up the thread for polling thread */ th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start the device-polling thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } dev->polling_thread = th; pci_set_drvdata(pci, dev); return 0; /* We come here if there are any problems */ errout: dev_err(&pci->dev, "rtsx_probe() failed\n"); release_everything(dev); return err; }
int main(int argc, char **argv) { int input_fd; int output_fd; int fft_dev_fd; int result; IN_SAMPLE_TYPE *in_buf; OUT_SAMPLE_TYPE *out_buf; initialize_everything(argc, argv); /* allocate storage for input, output and config buffers */ in_buf = (IN_SAMPLE_TYPE*) NE10_MALLOC (FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(in_buf == NULL) error(1, errno, "in_buf allocation"); out_buf = (OUT_SAMPLE_TYPE*) NE10_MALLOC (FFT_POINTS * sizeof(OUT_SAMPLE_TYPE)); if(out_buf == NULL) error(1, errno, "out_buf allocation"); /* open the input and output files and fft dev */ input_fd = open(g_input_filename, O_RDONLY); if(input_fd < 0) error(1, errno, "opening input file '%s'", g_input_filename); output_fd = open(g_output_filename, O_WRONLY | O_CREAT); if(output_fd < 0) error(1, errno, "opening output file '%s'", g_output_filename); fft_dev_fd = open("/dev/fft", O_RDWR); if(fft_dev_fd < 0) error(1, errno, "opening fft_dev_fd"); /* capture the start value of the GT */ g_start_time = get_gt_value(); /* read the input data */ result = read(input_fd, in_buf, FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "read input file"); if(result != (FFT_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "input data size, expected %d but got %d", FFT_POINTS * sizeof(IN_SAMPLE_TYPE), result); /* perform FFT with FPGA hardware, 16 bit input 24/32 bit output */ result = write(fft_dev_fd, in_buf, FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "write to fft_dev_fd"); if (result != (int)(FFT_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "fft_dev_fd input data size, expected %d but got %d", FFT_POINTS * sizeof(IN_SAMPLE_TYPE), result); result = read(fft_dev_fd, out_buf, FFT_POINTS * sizeof(OUT_SAMPLE_TYPE)); if(result < 0) error(1, errno, "read from fft_dev_fd"); if (result != (int)(FFT_POINTS * sizeof(OUT_SAMPLE_TYPE))) error(1, 0, "fft_dev_fd output data size, expected %d but got %d", FFT_POINTS * sizeof(OUT_SAMPLE_TYPE), result); /* write the output data */ result = write(output_fd, out_buf, FFT_POINTS * sizeof(OUT_SAMPLE_TYPE)); if(result < 0) error(1, errno, "write output file"); if(result != (FFT_POINTS * sizeof(OUT_SAMPLE_TYPE))) error(1, 0, "output data size, expected %d but got %d", FFT_POINTS * sizeof(OUT_SAMPLE_TYPE), result); /* capture the end value of the GT */ g_end_time = get_gt_value(); /* close the input and output files and fft dev */ close(fft_dev_fd); close(output_fd); close(input_fd); /* free storage for input, output and config buffers */ NE10_FREE (out_buf); NE10_FREE (in_buf); print_results(); release_everything(); return 0; }
//probe书中有教 static int our_probe(struct usb_interface *intf, const struct usb_device_id *id){ struct us_data *us; int result; //device struct device *dev; //scsihost struct Scsi_Host *host; //检测id是否符合 和intf struct us_unusual_dev *unusual_dev; unusual_dev=(id - usb_storage_usb_ids) + us_unusual_dev_list; if(usb_usual_check_type(id,USB_US_TYPE_STOR) || usb_usual_ignore_device(intf)) return -ENXIO; printk(KERN_ALERT "probe usb usb detected!\n"); //分配个host host = scsi_host_alloc(&usb_stor_host_template,sizeof(*us)); if(!host){ dev_warn(&intf->dev,"fail to allocate the scsi host\n"); return -ENOMEM; } //host中的一些初始化 host->max_cmd_len = 16; host-> sg_tablesize = usb_stor_sg_tablesize(intf); us= host_to_us(host);//us 作为host中 的us //分内存? memset(us,0,sizeof(struct us_data)); mutex_init(&(us->dev_mutex)); init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); INIT_DELAYED_WORK(&us->scan_dwork,usb_stor_scan_dwork); result = associate_dev(us,intf); if(result) goto Bad; result = get_device_info(us,id,unusual_dev); if(result) goto Bad; //transport protocol get_transport(us); get_protocol(us); if(!us->transport ||!us->proto_handler){ result=-ENXIO; goto Bad; } printk(KERN_ALERT"Transport: %s\n",us->transport_name); printk(KERN_ALERT"Protocol: %s\n",us->transport_name); dev = &us->pusb_intf->dev; //设置max lun if(us->fflags & US_FL_SINGLE_LUN) us->max_lun =0; //endpoint get pipe result = get_pipes(us); if(result) goto Bad; //如果u盘前十个指令错误,重置 if (us->fflags & US_FL_INITIAL_READ10) set_bit(US_FLIDX_REDO_READ10, &us->dflags); //申请子资源,添加进host result=usb_stor_acquire_sesources(us); if(result) goto Bad; snprintf(us->scsi_name,sizeof(us->scsi_name),"our-usb-storage%s",dev_name(&us->pusb_intf->dev)); result= scsi_add_host(us_to_host(us),dev); if(result){ printk(KERN_ALERT"UNable to add the host\n"); goto Bad; } //scsi设备延时探测 usb_autopm_get_interface_no_resume(us->pusb_intf); set_bit(US_FLIDX_SCAN_PENDING,&us->dflags); if(delay_use>0) dev_dbg(dev,"waiting for device before scanning\n"); queue_delayed_work(system_freezable_wq,&us->scan_dwork,delay_use * HZ); return 0; Bad: printk(KERN_ALERT "probe false!\n"); release_everything(us); return result; }
int main(int argc, char **argv) { int input_fd; int output_fd; int result; IN_SAMPLE_TYPE *in_buf; OUT_SAMPLE_TYPE *out_buf; CFG_TYPE cfg; int i; initialize_everything(argc, argv); /* allocate storage for input, output and config buffers */ in_buf = (IN_SAMPLE_TYPE*) NE10_MALLOC (FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(in_buf == NULL) error(1, errno, "in_buf allocation"); out_buf = (OUT_SAMPLE_TYPE*) NE10_MALLOC (FFT_POINTS * sizeof(OUT_SAMPLE_TYPE)); if(out_buf == NULL) error(1, errno, "out_buf allocation"); cfg = CFG_ALLOC_FUNC(FFT_CALC_POINTS); if(cfg == NULL) error(1, errno, "cfg allocation"); /* open the input and output files */ input_fd = open(g_input_filename, O_RDONLY); if(input_fd < 0) error(1, errno, "opening input file '%s'", g_input_filename); output_fd = open(g_output_filename, O_WRONLY | O_CREAT); if(output_fd < 0) error(1, errno, "opening output file '%s'", g_output_filename); /* capture the start value of the GT */ g_start_time = get_gt_value(); /* read the input data */ result = read(input_fd, in_buf, FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "read input file"); if(result != (FFT_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "input data size, expected %d but got %d", FFT_POINTS * sizeof(IN_SAMPLE_TYPE), result); /* compute FFT */ for (i = 0; i < FFT_CALC_ROUNDS ; i++) { FFT_FUNC(out_buf + (i * FFT_CALC_POINTS), in_buf + (i * FFT_CALC_POINTS), cfg, 0, 1); } /* write the output data */ result = write(output_fd, out_buf, FFT_POINTS * sizeof(OUT_SAMPLE_TYPE)); if(result < 0) error(1, errno, "write output file"); if(result != (FFT_POINTS * sizeof(OUT_SAMPLE_TYPE))) error(1, 0, "output data size, expected %d but got %d", FFT_POINTS * sizeof(OUT_SAMPLE_TYPE), result); /* capture the end value of the GT */ g_end_time = get_gt_value(); /* close the input and output files */ close(output_fd); close(input_fd); /* free storage for input, output and config buffers */ NE10_FREE (cfg); NE10_FREE (out_buf); NE10_FREE (in_buf); print_results(); release_everything(); return 0; }
int main(int argc, char **argv) { int input_fd; int output_fd; int raw256stream_dev_fd; int result; IN_SAMPLE_TYPE *in_buf; int j; initialize_everything(argc, argv); /* allocate storage for input */ in_buf = (IN_SAMPLE_TYPE*) NE10_MALLOC (FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(in_buf == NULL) error(1, errno, "in_buf allocation"); /* open the input and output files and raw256stream device */ input_fd = open(g_input_filename, O_RDONLY); if(input_fd < 0) error(1, errno, "opening input file '%s'", g_input_filename); output_fd = open(g_output_filename, O_WRONLY | O_CREAT); if(output_fd < 0) error(1, errno, "opening output file '%s'", g_output_filename); raw256stream_dev_fd = open("/dev/raw256stream", O_RDWR); if(raw256stream_dev_fd < 0) error(1, errno, "opening raw256stream_dev_fd"); /* read the input data */ result = read(input_fd, in_buf, FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "read input file"); if(result != (FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "input data size, expected %d but got %d", FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE), result); /* write the waveform buffer */ result = write(raw256stream_dev_fd, in_buf, FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "write waveform buffer"); if(result != (FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "output data size, expected %d but got %d", FFT_CALC_POINTS * sizeof(IN_SAMPLE_TYPE), result); /* capture the start value of the GT */ g_start_time = get_gt_value(); for(j = 0 ; j < FFT_IN_ROUNDS ; j++) { /* read the input stream */ result = read(raw256stream_dev_fd, in_buf, FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "read input stream"); if(result != (FFT_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "input data size, expected %d but got %d", FFT_POINTS * sizeof(IN_SAMPLE_TYPE), result); /* write the output data */ result = write(output_fd, in_buf, FFT_POINTS * sizeof(IN_SAMPLE_TYPE)); if(result < 0) error(1, errno, "write output file"); if(result != (FFT_POINTS * sizeof(IN_SAMPLE_TYPE))) error(1, 0, "output data size, expected %d but got %d", FFT_POINTS * sizeof(IN_SAMPLE_TYPE), result); } /* capture the end value of the GT */ g_end_time = get_gt_value(); /* close the input and output files and stream device */ close(raw256stream_dev_fd); close(output_fd); close(input_fd); /* free storage for input, output and config buffers */ NE10_FREE (in_buf); print_results(); release_everything(); return 0; }
static int rtsx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct Scsi_Host *host; struct rtsx_dev *dev; int err = 0; struct task_struct *th; printk(KERN_INFO "--- %s ---\n", DRIVER_MAKE_TIME); err = pci_enable_device(pci); if (err < 0) { printk(KERN_ERR "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { printk(KERN_ERR "PCI request regions for %s failed!\n", CR_DRIVER_NAME); pci_disable_device(pci); return err; } /* * Ask the SCSI layer to allocate a host structure, with extra * space at the end for our private rtsx_dev structure. */ host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); if (!host) { printk(KERN_ERR "Unable to allocate the scsi host\n"); pci_release_regions(pci); pci_disable_device(pci); return -ENOMEM; } dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); dev->chip = (struct rtsx_chip *)kmalloc(sizeof(struct rtsx_chip), GFP_KERNEL); if (dev->chip == NULL) { goto errout; } memset(dev->chip, 0, sizeof(struct rtsx_chip)); spin_lock_init(&dev->reg_lock); mutex_init(&(dev->dev_mutex)); sema_init(&(dev->sema), 0); init_completion(&(dev->notify)); init_waitqueue_head(&dev->delay_wait); dev->pci = pci; dev->irq = -1; printk(KERN_INFO "Resource length: 0x%x\n", (unsigned int)pci_resource_len(pci,0)); dev->addr = pci_resource_start(pci, 0); dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci,0)); if (dev->remap_addr == NULL) { printk(KERN_ERR "ioremap error\n"); err = -ENXIO; goto errout; } printk(KERN_INFO "Original address: 0x%lx, remapped address: 0x%lx\n", (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, &(dev->rtsx_resv_buf_addr), GFP_KERNEL); if (dev->rtsx_resv_buf == NULL) { printk(KERN_ERR "alloc dma buffer fail\n"); err = -ENXIO; goto errout; } dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; dev->chip->rtsx = dev; rtsx_init_options(dev->chip); printk(KERN_INFO "pci->irq = %d\n", pci->irq); if (dev->chip->msi_en) { if (pci_enable_msi(pci) < 0) { dev->chip->msi_en = 0; } } if (rtsx_acquire_irq(dev) < 0) { err = -EBUSY; goto errout; } pci_set_master(pci); synchronize_irq(dev->irq); err = scsi_add_host(host, &pci->dev); if (err) { printk(KERN_ERR "Unable to add the scsi host\n"); goto errout; } rtsx_init_chip(dev->chip); th = kthread_create(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start control thread\n"); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the control thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the scanning thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); th = kthread_create(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-polling thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the polling thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); pci_set_drvdata(pci, dev); return 0; errout: printk(KERN_ERR "rtsx_probe() failed\n"); release_everything(dev); return err; }
static int rts51x_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct Scsi_Host *host; struct rts51x_chip *chip; struct rts51x_usb *rts51x; int result; struct task_struct *th; RTS51X_DEBUGP("%s detected\n", RTS51X_NAME); rts51x = kzalloc(sizeof(struct rts51x_usb), GFP_KERNEL); if (!rts51x) { printk(KERN_WARNING RTS51X_TIP "Unable to allocate rts51x_usb\n"); return -ENOMEM; } host = scsi_host_alloc(&rts51x_host_template, sizeof(*chip)); if (!host) { printk(KERN_WARNING RTS51X_TIP "Unable to allocate the scsi host\n"); kfree(rts51x); return -ENOMEM; } host->max_cmd_len = 16; chip = host_to_rts51x(host); memset(chip, 0, sizeof(struct rts51x_chip)); chip->vendor_id = id->idVendor; chip->product_id = id->idProduct; mutex_init(&(rts51x->dev_mutex)); init_completion(&rts51x->cmnd_ready); init_completion(&rts51x->control_exit); init_completion(&rts51x->polling_exit); init_completion(&(rts51x->notify)); #ifdef SCSI_SCAN_DELAY init_waitqueue_head(&rts51x->delay_wait); init_completion(&rts51x->scanning_done); #endif chip->usb = rts51x; result = associate_dev(chip, intf); if (result) goto BadDevice; result = get_pipes(chip); if (result) goto BadDevice; result = rts51x_acquire_resources(chip); if (result) goto BadDevice; th = kthread_run(rts51x_control_thread, chip, RTS51X_CTL_THREAD); if (IS_ERR(th)) { printk(KERN_WARNING RTS51X_TIP "Unable to start control thread\n"); result = PTR_ERR(th); goto BadDevice; } rts51x->ctl_thread = th; result = scsi_add_host(rts51x_to_host(chip), &rts51x->pusb_intf->dev); if (result) { printk(KERN_WARNING RTS51X_TIP "Unable to add the scsi host\n"); goto BadDevice; } #ifdef SCSI_SCAN_DELAY th = kthread_create(rts51x_scan_thread, chip, RTS51X_SCAN_THREAD); if (IS_ERR(th)) { printk(KERN_WARNING RTS51X_TIP "Unable to start the device-scanning thread\n"); complete(&rts51x->scanning_done); quiesce_and_remove_host(chip); result = PTR_ERR(th); goto BadDevice; } wake_up_process(th); #else scsi_scan_host(rts51x_to_host(chip)); #endif th = kthread_run(rts51x_polling_thread, chip, RTS51X_POLLING_THREAD); if (IS_ERR(th)) { printk(KERN_WARNING RTS51X_TIP "Unable to start polling thread\n"); result = PTR_ERR(th); goto BadDevice; } rts51x->polling_thread = th; #ifdef CONFIG_PM if (ss_en) { rts51x->pusb_intf->needs_remote_wakeup = needs_remote_wakeup; SET_PM_USAGE_CNT(chip, 1); RTS51X_DEBUGP("pm_usage_cnt = %d\n", GET_PM_USAGE_CNT(chip)); } #endif return 0; BadDevice: RTS51X_DEBUGP("rts51x_probe() failed\n"); release_everything(chip); return result; }