Loading drivers/usb/gadget/f_mass_storage.c +51 −1 Original line number Diff line number Diff line Loading @@ -237,6 +237,14 @@ static int csw_hack_sent; #endif /*-------------------------------------------------------------------------*/ /*If USB mass storage vfs operation is stuck for more than 10 sec host will initiate the reset. Configure the timer with 9 sec to print the error message before host is intiating the resume on it.*/ #define MSC_VFS_TIMER_PERIOD_MS 9000 static int msc_vfs_timer_period_ms = MSC_VFS_TIMER_PERIOD_MS; module_param(msc_vfs_timer_period_ms, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(msc_vfs_timer_period_ms, "Set period for MSC VFS timer"); struct fsg_dev; struct fsg_common; Loading Loading @@ -315,6 +323,7 @@ struct fsg_common { char inquiry_string[8 + 16 + 4 + 1]; struct kref ref; struct timer_list vfs_timer; }; struct fsg_config { Loading Loading @@ -355,6 +364,26 @@ struct fsg_dev { struct usb_ep *bulk_out; }; static void msc_usb_vfs_timer_func(unsigned long data) { struct fsg_common *common = (struct fsg_common *) data; switch (common->data_dir) { case DATA_DIR_FROM_HOST: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_write\n"); break; case DATA_DIR_TO_HOST: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_read\n"); break; default: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_sync\n"); break; } } static inline int __fsg_is_set(struct fsg_common *common, const char *func, unsigned line) { Loading Loading @@ -745,9 +774,12 @@ static int do_read(struct fsg_common *common) #ifdef CONFIG_USB_MSC_PROFILING start = ktime_get(); #endif mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nread = vfs_read(curlun->filp, (char __user *)bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); #ifdef CONFIG_USB_MSC_PROFILING Loading Loading @@ -965,9 +997,12 @@ static int do_write(struct fsg_common *common) #ifdef CONFIG_USB_MSC_PROFILING start = ktime_get(); #endif mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nwritten); #ifdef CONFIG_USB_MSC_PROFILING Loading Loading @@ -1067,9 +1102,12 @@ static int do_synchronize_cache(struct fsg_common *common) /* We ignore the requested LBA and write out all file's * dirty data buffers. */ mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); rc = fsg_lun_fsync_sub(curlun); if (rc) curlun->sense_data = SS_WRITE_ERROR; del_timer_sync(&common->vfs_timer); return 0; } Loading Loading @@ -1125,7 +1163,10 @@ static int do_verify(struct fsg_common *common) file_offset = ((loff_t) lba) << curlun->blkbits; /* Write out all the dirty buffers before invalidating them */ mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); fsg_lun_fsync_sub(curlun); del_timer_sync(&common->vfs_timer); if (signal_pending(current)) return -EINTR; Loading Loading @@ -1155,9 +1196,12 @@ static int do_verify(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nread = vfs_read(curlun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); Loading Loading @@ -1487,8 +1531,12 @@ static int do_prevent_allow(struct fsg_common *common) curlun->sense_data = SS_INVALID_FIELD_IN_CDB; return -EINVAL; } if (!curlun->nofua && curlun->prevent_medium_removal && !prevent) if (!curlun->nofua && curlun->prevent_medium_removal && !prevent) { mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); fsg_lun_fsync_sub(curlun); del_timer_sync(&common->vfs_timer); } curlun->prevent_medium_removal = prevent; return 0; } Loading Loading @@ -3183,6 +3231,8 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, fsg->function.disable = fsg_disable; fsg->common = common; setup_timer(&common->vfs_timer, msc_usb_vfs_timer_func, (unsigned long) common); /* * Our caller holds a reference to common structure so we * don't have to be worry about it being freed until we return Loading Loading
drivers/usb/gadget/f_mass_storage.c +51 −1 Original line number Diff line number Diff line Loading @@ -237,6 +237,14 @@ static int csw_hack_sent; #endif /*-------------------------------------------------------------------------*/ /*If USB mass storage vfs operation is stuck for more than 10 sec host will initiate the reset. Configure the timer with 9 sec to print the error message before host is intiating the resume on it.*/ #define MSC_VFS_TIMER_PERIOD_MS 9000 static int msc_vfs_timer_period_ms = MSC_VFS_TIMER_PERIOD_MS; module_param(msc_vfs_timer_period_ms, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(msc_vfs_timer_period_ms, "Set period for MSC VFS timer"); struct fsg_dev; struct fsg_common; Loading Loading @@ -315,6 +323,7 @@ struct fsg_common { char inquiry_string[8 + 16 + 4 + 1]; struct kref ref; struct timer_list vfs_timer; }; struct fsg_config { Loading Loading @@ -355,6 +364,26 @@ struct fsg_dev { struct usb_ep *bulk_out; }; static void msc_usb_vfs_timer_func(unsigned long data) { struct fsg_common *common = (struct fsg_common *) data; switch (common->data_dir) { case DATA_DIR_FROM_HOST: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_write\n"); break; case DATA_DIR_TO_HOST: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_read\n"); break; default: dev_err(&common->curlun->dev, "usb mass storage stuck in vfs_sync\n"); break; } } static inline int __fsg_is_set(struct fsg_common *common, const char *func, unsigned line) { Loading Loading @@ -745,9 +774,12 @@ static int do_read(struct fsg_common *common) #ifdef CONFIG_USB_MSC_PROFILING start = ktime_get(); #endif mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nread = vfs_read(curlun->filp, (char __user *)bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); #ifdef CONFIG_USB_MSC_PROFILING Loading Loading @@ -965,9 +997,12 @@ static int do_write(struct fsg_common *common) #ifdef CONFIG_USB_MSC_PROFILING start = ktime_get(); #endif mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nwritten); #ifdef CONFIG_USB_MSC_PROFILING Loading Loading @@ -1067,9 +1102,12 @@ static int do_synchronize_cache(struct fsg_common *common) /* We ignore the requested LBA and write out all file's * dirty data buffers. */ mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); rc = fsg_lun_fsync_sub(curlun); if (rc) curlun->sense_data = SS_WRITE_ERROR; del_timer_sync(&common->vfs_timer); return 0; } Loading Loading @@ -1125,7 +1163,10 @@ static int do_verify(struct fsg_common *common) file_offset = ((loff_t) lba) << curlun->blkbits; /* Write out all the dirty buffers before invalidating them */ mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); fsg_lun_fsync_sub(curlun); del_timer_sync(&common->vfs_timer); if (signal_pending(current)) return -EINTR; Loading Loading @@ -1155,9 +1196,12 @@ static int do_verify(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); nread = vfs_read(curlun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); del_timer_sync(&common->vfs_timer); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); Loading Loading @@ -1487,8 +1531,12 @@ static int do_prevent_allow(struct fsg_common *common) curlun->sense_data = SS_INVALID_FIELD_IN_CDB; return -EINVAL; } if (!curlun->nofua && curlun->prevent_medium_removal && !prevent) if (!curlun->nofua && curlun->prevent_medium_removal && !prevent) { mod_timer(&common->vfs_timer, jiffies + msecs_to_jiffies(msc_vfs_timer_period_ms)); fsg_lun_fsync_sub(curlun); del_timer_sync(&common->vfs_timer); } curlun->prevent_medium_removal = prevent; return 0; } Loading Loading @@ -3183,6 +3231,8 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, fsg->function.disable = fsg_disable; fsg->common = common; setup_timer(&common->vfs_timer, msc_usb_vfs_timer_func, (unsigned long) common); /* * Our caller holds a reference to common structure so we * don't have to be worry about it being freed until we return Loading