Two configuration were added to the mass storage gadget: BOT (the first one), and UAS. The linux host can switch between the configurations by changing the value of bConfigValue in /sys/bus/usb/devices/<your_usb_device>/ Also, a fallback to HS in case SS configuration fails was added. Signed-off-by: Shimrit Malichi <smalichi@xxxxxxxxxxxxxx> --- drivers/usb/gadget/f_mass_storage.c | 92 +--- drivers/usb/gadget/f_uasp.c | 1063 ++++++++++++++++++++--------------- drivers/usb/gadget/f_uasp.h | 106 +++- drivers/usb/gadget/mass_storage.c | 88 ++-- drivers/usb/gadget/storage_common.c | 66 +++- drivers/usb/gadget/uasp_cmdiu.c | 176 +++--- drivers/usb/gadget/uasp_tmiu.c | 60 +- 7 files changed, 955 insertions(+), 696 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index b777d72..96da3f6 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -317,39 +317,16 @@ static const char fsg_string_interface[] = "Mass Storage"; struct fsg_dev; struct fsg_common; -/* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); - - /* - * Called prior to ejection. Negative return means error, - * zero means to continue with ejection, positive means not to - * eject. - */ - int (*pre_eject)(struct fsg_common *common, - struct fsg_lun *lun, int num); - /* - * Called after ejection. Negative return means error, zero - * or positive is just a success. - */ - int (*post_eject)(struct fsg_common *common, - struct fsg_lun *lun, int num); -}; - /* Data shared by all the FSG instances. */ struct fsg_common { struct usb_gadget *gadget; struct usb_composite_dev *cdev; + struct msg_common_data *msg_common; struct fsg_dev *fsg, *new_fsg; wait_queue_head_t fsg_wait; + struct mutex *config_mutex; + /* filesem protects: backing files in use */ struct rw_semaphore filesem; @@ -408,31 +385,6 @@ struct fsg_common { struct kref ref; }; -struct fsg_config { - unsigned nluns; - struct fsg_lun_config { - const char *filename; - char ro; - char removable; - char cdrom; - char nofua; - } luns[FSG_MAX_LUNS]; - - const char *lun_name_format; - const char *thread_name; - - /* Callback functions. */ - const struct fsg_operations *ops; - /* Gadget's private data. */ - void *private_data; - - const char *vendor_name; /* 8 characters or less */ - const char *product_name; /* 16 characters or less */ - u16 release; - - char can_stall; -}; - struct fsg_dev { struct usb_function function; struct usb_gadget *gadget; /* Copy of cdev->gadget */ @@ -2364,7 +2316,10 @@ reset: usb_ep_disable(fsg->bulk_out); fsg->bulk_out_enabled = 0; } - + DBG(common, + "%s()- disabled endpoints, releasing config mutex\n", + __func__); + mutex_unlock(common->config_mutex); common->fsg = NULL; wake_up(&common->fsg_wait); } @@ -2373,6 +2328,9 @@ reset: if (!new_fsg || rc) return rc; + DBG(common, "%s()- Enabling endpoints, taking config mutex\n", + __func__); + mutex_lock(common->config_mutex); common->fsg = new_fsg; fsg = common->fsg; @@ -2703,8 +2661,7 @@ static inline void fsg_common_put(struct fsg_common *common) static struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev, - struct fsg_config *cfg, - int start_thread) + struct fsg_config *cfg) { struct usb_gadget *gadget = cdev->gadget; struct fsg_buffhd *bh; @@ -2750,6 +2707,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, common->ep0 = gadget->ep0; common->ep0req = cdev->req; common->cdev = cdev; + common->config_mutex = &(cfg->config_mutex); /* Maybe allocate device-global string IDs, and patch descriptors */ if (fsg_strings[FSG_STRING_INTERFACE].id == 0) { @@ -2866,15 +2824,12 @@ buffhds_first_it: spin_lock_init(&common->lock); kref_init(&common->ref); - /* Tell the thread to start working */ - if (start_thread) { - common->thread_task = - kthread_create(fsg_main_thread, common, - cfg->thread_name ?: "file-storage"); - if (IS_ERR(common->thread_task)) { - rc = PTR_ERR(common->thread_task); - goto error_release; - } + common->thread_task = + kthread_create(fsg_main_thread, common, + cfg->thread_name ?: "file-storage"); + if (IS_ERR(common->thread_task)) { + rc = PTR_ERR(common->thread_task); + goto error_release; } init_completion(&common->thread_notifier); init_waitqueue_head(&common->fsg_wait); @@ -2905,11 +2860,10 @@ buffhds_first_it: } kfree(pathbuf); - if (start_thread) { - DBG(common, "I/O thread pid: %d\n", - task_pid_nr(common->thread_task)); - wake_up_process(common->thread_task); - } + DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); + + wake_up_process(common->thread_task); + return common; error_luns: @@ -3200,6 +3154,6 @@ fsg_common_from_params(struct fsg_common *common, { struct fsg_config cfg; fsg_config_from_params(&cfg, params); - return fsg_common_init(common, cdev, &cfg, 1); + return fsg_common_init(common, cdev, &cfg); } diff --git a/drivers/usb/gadget/f_uasp.c b/drivers/usb/gadget/f_uasp.c index 3db5a11..f3d1efa 100644 --- a/drivers/usb/gadget/f_uasp.c +++ b/drivers/usb/gadget/f_uasp.c @@ -176,11 +176,9 @@ #include <linux/kref.h> #include <linux/kthread.h> #include <linux/string.h> -#include <linux/usb/ch9.h> -#include <linux/usb/gadget.h> -#include <linux/kernel.h> #include <linux/usb/storage.h> +#include "f_uasp.h" #include "uasp_cmdiu.c" #include "uasp_tmiu.c" @@ -201,20 +199,21 @@ uasp_intf_desc = { /* BULK-in pipe descriptors */ static struct usb_endpoint_descriptor -uasp_bulk_in_desc = { +uasp_fs_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(64), }; -struct usb_pipe_usage_descriptor -uasp_bulk_in_pipe_usg_desc = { - .bLength = sizeof uasp_bulk_in_pipe_usg_desc, - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = PIPE_ID_DATA_IN, - .Reserved = 0, +static struct usb_endpoint_descriptor +uasp_hs_bulk_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), }; struct usb_endpoint_descriptor @@ -238,22 +237,31 @@ uasp_bulk_in_ep_comp_desc = { .wBytesPerInterval = 0, }; +struct usb_pipe_usage_descriptor +uasp_bulk_in_pipe_usg_desc = { + .bLength = sizeof uasp_bulk_in_pipe_usg_desc, + .bDescriptorType = USB_DT_PIPE_USAGE, + .bPipeID = PIPE_ID_DATA_IN, + .Reserved = 0, +}; + /* BULK-out pipe descriptors */ struct usb_endpoint_descriptor -uasp_bulk_out_desc = { +uasp_fs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(64), }; -struct usb_pipe_usage_descriptor -uasp_bulk_out_pipe_usg_desc = { - .bLength = sizeof uasp_bulk_out_pipe_usg_desc, - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = PIPE_ID_DATA_OUT, - .Reserved = 0, +struct usb_endpoint_descriptor +uasp_hs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), }; struct usb_endpoint_descriptor @@ -277,22 +285,31 @@ uasp_bulk_out_ep_comp_desc = { .wBytesPerInterval = 0, }; +struct usb_pipe_usage_descriptor +uasp_bulk_out_pipe_usg_desc = { + .bLength = sizeof uasp_bulk_out_pipe_usg_desc, + .bDescriptorType = USB_DT_PIPE_USAGE, + .bPipeID = PIPE_ID_DATA_OUT, + .Reserved = 0, +}; + /* Status pipe - descriptors */ struct usb_endpoint_descriptor -uasp_status_in_desc = { +uasp_fs_status_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(64), }; -struct usb_pipe_usage_descriptor -uasp_status_in_pipe_usg_desc = { - .bLength = sizeof uasp_status_in_pipe_usg_desc, - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = PIPE_ID_STS, - .Reserved = 0, +struct usb_endpoint_descriptor +uasp_hs_status_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), }; struct usb_endpoint_descriptor @@ -316,22 +333,32 @@ uasp_status_in_ep_comp_desc = { .wBytesPerInterval = 0, }; + +struct usb_pipe_usage_descriptor +uasp_status_in_pipe_usg_desc = { + .bLength = sizeof uasp_status_in_pipe_usg_desc, + .bDescriptorType = USB_DT_PIPE_USAGE, + .bPipeID = PIPE_ID_STS, + .Reserved = 0, +}; + /* Command pipe descriptors */ struct usb_endpoint_descriptor -uasp_command_out_desc = { +uasp_fs_command_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = cpu_to_le16(512), + .wMaxPacketSize = cpu_to_le16(64), }; -struct usb_pipe_usage_descriptor -uasp_command_out_pipe_usg_desc = { - .bLength = sizeof uasp_command_out_pipe_usg_desc, - .bDescriptorType = USB_DT_PIPE_USAGE, - .bPipeID = PIPE_ID_CMD, - .Reserved = 0, +struct usb_endpoint_descriptor +uasp_hs_command_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(512), }; struct usb_endpoint_descriptor @@ -355,16 +382,38 @@ uasp_command_out_ep_comp_desc = { .wBytesPerInterval = 0, }; +struct usb_pipe_usage_descriptor +uasp_command_out_pipe_usg_desc = { + .bLength = sizeof uasp_command_out_pipe_usg_desc, + .bDescriptorType = USB_DT_PIPE_USAGE, + .bPipeID = PIPE_ID_CMD, + .Reserved = 0, +}; + +/* FS configuration function descriptors */ +struct usb_descriptor_header *uasp_fs_function_desc[] = { + (struct usb_descriptor_header *) &uasp_intf_desc, + (struct usb_descriptor_header *) &uasp_fs_bulk_in_desc, + (struct usb_descriptor_header *) &uasp_bulk_in_pipe_usg_desc, + (struct usb_descriptor_header *) &uasp_fs_bulk_out_desc, + (struct usb_descriptor_header *) &uasp_bulk_out_pipe_usg_desc, + (struct usb_descriptor_header *) &uasp_fs_status_in_desc, + (struct usb_descriptor_header *) &uasp_status_in_pipe_usg_desc, + (struct usb_descriptor_header *) &uasp_fs_command_out_desc, + (struct usb_descriptor_header *) &uasp_command_out_pipe_usg_desc, + NULL, +}; + /* HS configuration function descriptors */ struct usb_descriptor_header *uasp_hs_function_desc[] = { (struct usb_descriptor_header *) &uasp_intf_desc, - (struct usb_descriptor_header *) &uasp_bulk_in_desc, + (struct usb_descriptor_header *) &uasp_hs_bulk_in_desc, (struct usb_descriptor_header *) &uasp_bulk_in_pipe_usg_desc, - (struct usb_descriptor_header *) &uasp_bulk_out_desc, + (struct usb_descriptor_header *) &uasp_hs_bulk_out_desc, (struct usb_descriptor_header *) &uasp_bulk_out_pipe_usg_desc, - (struct usb_descriptor_header *) &uasp_status_in_desc, + (struct usb_descriptor_header *) &uasp_hs_status_in_desc, (struct usb_descriptor_header *) &uasp_status_in_pipe_usg_desc, - (struct usb_descriptor_header *) &uasp_command_out_desc, + (struct usb_descriptor_header *) &uasp_hs_command_out_desc, (struct usb_descriptor_header *) &uasp_command_out_pipe_usg_desc, NULL, }; @@ -388,35 +437,61 @@ struct usb_descriptor_header *uasp_ss_function_desc[] = { }; /*--------------------------------------------------------------------------*/ +static int uasp_exception_in_progress(struct uasp_common *common) +{ + return common->state > UASP_STATE_IDLE; +} + +/* Caller must hold udev->lock */ +static void uasp_wakeup_thread(struct uasp_common *common) +{ + /* Tell the main thread that something has happened */ + common->thread_wakeup_needed = 1; + if (common->thread_task) + wake_up_process(common->thread_task); +} + static inline struct uasp_dev *uaspd_from_func(struct usb_function *f) { - struct fsg_dev *fsg_dev = fsg_from_func(f); - return container_of(fsg_dev, struct uasp_dev, fsg_dev); + return container_of(f, struct uasp_dev, function); +} + +static void uasp_raise_exception(struct uasp_common *common, + enum fsg_state new_state) +{ + unsigned long flags; + + /* + * Do nothing if a higher-priority exception is already in progress. + * If a lower-or-equal priority exception is in progress, preempt it + * and notify the main thread by sending it a signal. + */ + spin_lock_irqsave(&common->lock, flags); + if (common->state <= new_state) { + common->state = new_state; + if (common->thread_task) + send_sig_info(SIGUSR1, SEND_SIG_FORCED, + common->thread_task); + } + spin_unlock_irqrestore(&common->lock, flags); } static void uasp_common_release(struct kref *ref) { struct uasp_common *ucommon = container_of(ref, struct uasp_common, ref); - struct uasp_lun *ulun; - int i; - /* First stop all lun threads */ - run_lun_threads(ucommon->udev, LUN_STATE_EXIT); - for (i = 0; i < ucommon->common->nluns; i++) { - ulun = &(ucommon->uluns[i]); - if (ulun->lun_state != LUN_STATE_TERMINATED) { - wait_for_completion(&ulun->thread_notifier); - /* The cleanup routine waits for this completion also */ - complete(&ulun->thread_notifier); - } + /* If the thread isn't already dead, tell it to exit now */ + if (ucommon->state != UASP_STATE_TERMINATED) { + uasp_raise_exception(ucommon, FSG_STATE_EXIT); + wait_for_completion(&ucommon->thread_notifier); } - fsg_common_release(&(ucommon->common->ref)); + kfree(ucommon->uluns); + kfree(ucommon->ubufs); kfree(ucommon); } - static inline void uasp_common_put(struct uasp_common *common) { kref_put(&(common->ref), uasp_common_release); @@ -427,23 +502,48 @@ static struct uasp_lun *find_lun_by_id(struct uasp_dev *udev, __u8 *lun_id) int i; struct uasp_lun *curlun; - DBG(udev->ucommon->common, "%s() - Enter.\n", __func__); + DBG(udev->ucommon, "%s() - Enter.\n", __func__); - for (i = 0; i < udev->ucommon->common->nluns; ++i) { + for (i = 0; i < udev->ucommon->nluns; ++i) { curlun = &udev->ucommon->uluns[i]; if (memcmp(lun_id, curlun->lun_id, 8) == 0) { - DBG(udev->ucommon->common, "%s() - LUN found\n", + DBG(udev->ucommon, "%s() - LUN found\n", __func__); return curlun; } } - DBG(udev->ucommon->common, "%s() - LUN not found\n", __func__); + DBG(udev->ucommon, "%s() - LUN not found\n", __func__); return 0; } /** - * wakeup_lun_thread() - Wakes up the given LUn thread + * uasp_sleep_thread() - sleep UASP main thread + * @common: pointer to uasp common data structure + */ +int uasp_sleep_thread(struct uasp_common *common) +{ + int rc = 0; + + /* Wait until a signal arrives or we are woken up */ + for (;;) { + try_to_freeze(); + set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) { + rc = -EINTR; + break; + } + if (common->thread_wakeup_needed) + break; + schedule(); + } + __set_current_state(TASK_RUNNING); + common->thread_wakeup_needed = 0; + return rc; +} + +/** + * wakeup_lun_thread() - Wakes up the given LUN thread * @lun: the LUN which thread needs wakening * * NOTE: Caller must hold uasp_lun->lock @@ -472,31 +572,31 @@ static void command_complete(struct usb_ep *ep, struct usb_request *req) unsigned long flags; if (req->actual > 0) - dump_msg(udev->ucommon->common, "command", req->buf, + dump_msg(udev->ucommon, "command", req->buf, req->actual); - DBG(udev->ucommon->common, "%s() - Enter", __func__); + DBG(udev->ucommon, "%s() - Enter", __func__); if (req != udev->cmd_buff.outreq) { - ERROR(udev->ucommon->common, "(%s) req(%p) != " + ERROR(udev->ucommon, "(%s) req(%p) != " "cmd_buff.outreq(%p), udev=%p," " common->state = %d\n", __func__, req, udev->cmd_buff.outreq, udev, - udev->ucommon->common->state); + udev->ucommon->state); } if (req->status == -ECONNRESET) { - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); udev->cmd_buff.state = BUF_STATE_EMPTY; - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); usb_ep_fifo_flush(ep); return; } - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); udev->cmd_buff.state = BUF_STATE_FULL; - wakeup_thread(udev->ucommon->common); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + uasp_wakeup_thread(udev->ucommon); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); } /** @@ -520,12 +620,12 @@ void status_complete(struct usb_ep *ep, struct usb_request *req) uint8_t cmd_id = ((uint8_t *)req->context)[0]; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter", __func__); + DBG(udev->ucommon, "%s() - Enter", __func__); if (req->status == -ECONNRESET) usb_ep_fifo_flush(ep); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); /* If Sense IU is filled for TM FUNCTION IU */ if (cmd_id == IU_ID_TASK_MANAGEMENT) { tmiu = (struct tm_iu *)req->context; @@ -534,14 +634,14 @@ void status_complete(struct usb_ep *ep, struct usb_request *req) if (req->status == -ERESTART) tmiu->state = COMMAND_STATE_ABORTED; else if (req->status) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - TMIU FAILED!!! Status = %d", __func__, req->status); tmiu->state = COMMAND_STATE_FAILED; } else tmiu->state = COMMAND_STATE_COMPLETED; } - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - received IU_ID_TASK_MANAGEMENT " "(Code = %02x tmiu->state = %d)\n", __func__, tmiu->tm_function, tmiu->state); @@ -556,14 +656,14 @@ void status_complete(struct usb_ep *ep, struct usb_request *req) if (req->status == -ERESTART) cmdiu->state = COMMAND_STATE_ABORTED; else if (req->status) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - CMDIU FAILED!!! Status = %d", __func__, req->status); cmdiu->state = COMMAND_STATE_FAILED; } else if (cmdiu->state == COMMAND_STATE_STATUS) cmdiu->state = COMMAND_STATE_COMPLETED; } - DBG(udev->ucommon->common, "%s() - received IU_ID_COMMAND" + DBG(udev->ucommon, "%s() - received IU_ID_COMMAND" " (OpCode = %02x, smdiu->state = %d)\n", __func__, cmdiu->cdb[0], cmdiu->state); cmdiu->req_sts = CMD_REQ_COMPLETED; @@ -571,29 +671,29 @@ void status_complete(struct usb_ep *ep, struct usb_request *req) curlun = find_lun_by_id(udev, cmdiu->lun); } else { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - received invalid IU (iu_id = %02x)!\n", __func__, cmd_id); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); return; } if (curlun) { - spin_unlock_irqrestore(&(udev->ucommon->common->lock), + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); spin_lock_irqsave(&(curlun->lock), flags); curlun->pending_requests++; curlun->active_requests--; wakeup_lun_thread(curlun); spin_unlock_irqrestore(&(curlun->lock), flags); - spin_lock_irqsave(&(udev->ucommon->common->lock), + spin_lock_irqsave(&(udev->ucommon->lock), flags); } else { udev->pending_requests++; udev->active_requests--; - wakeup_thread(udev->ucommon->common); + uasp_wakeup_thread(udev->ucommon); } - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); } /** @@ -613,14 +713,14 @@ void uasp_bulk_in_complete(struct usb_ep *ep, struct usb_request *req) struct cmd_iu *cmdiu; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (req->status == -ECONNRESET) usb_ep_fifo_flush(ep); cmdiu = (struct cmd_iu *)req->context; - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); if (cmdiu->state != COMMAND_STATE_ABORTED && cmdiu->state != COMMAND_STATE_FAILED) { if (req->status == -ERESTART) @@ -635,19 +735,19 @@ void uasp_bulk_in_complete(struct usb_ep *ep, struct usb_request *req) curlun = find_lun_by_id(udev, cmdiu->lun); if (curlun) { - spin_unlock_irqrestore(&udev->ucommon->common->lock, flags); + spin_unlock_irqrestore(&udev->ucommon->lock, flags); spin_lock_irqsave(&curlun->lock, flags); curlun->pending_requests++; curlun->active_requests--; wakeup_lun_thread(curlun); spin_unlock_irqrestore(&curlun->lock, flags); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); } else { udev->pending_requests++; udev->active_requests--; - wakeup_thread(udev->ucommon->common); + uasp_wakeup_thread(udev->ucommon); } - spin_unlock_irqrestore(&udev->ucommon->common->lock, flags); + spin_unlock_irqrestore(&udev->ucommon->lock, flags); } @@ -668,12 +768,12 @@ void uasp_bulk_out_complete(struct usb_ep *ep, struct usb_request *req) struct cmd_iu *cmdiu; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (req->status == -ECONNRESET) usb_ep_fifo_flush(ep); - spin_lock_irqsave(&udev->ucommon->common->lock, flags); + spin_lock_irqsave(&udev->ucommon->lock, flags); cmdiu = (struct cmd_iu *)req->context; if (cmdiu->state != COMMAND_STATE_ABORTED && @@ -689,19 +789,19 @@ void uasp_bulk_out_complete(struct usb_ep *ep, struct usb_request *req) curlun = find_lun_by_id(udev, cmdiu->lun); if (curlun) { - spin_unlock_irqrestore(&udev->ucommon->common->lock, flags); + spin_unlock_irqrestore(&udev->ucommon->lock, flags); spin_lock_irqsave(&curlun->lock, flags); curlun->pending_requests++; curlun->active_requests--; wakeup_lun_thread(curlun); spin_unlock_irqrestore(&curlun->lock, flags); - spin_lock_irqsave(&udev->ucommon->common->lock, flags); + spin_lock_irqsave(&udev->ucommon->lock, flags); } else { udev->pending_requests++; udev->active_requests--; - wakeup_thread(udev->ucommon->common); + uasp_wakeup_thread(udev->ucommon); } - spin_unlock_irqrestore(&udev->ucommon->common->lock, flags); + spin_unlock_irqrestore(&udev->ucommon->lock, flags); } /** @@ -722,11 +822,11 @@ static void remove_completed_commands(struct uasp_dev *udev, struct tm_iu *tmiu; struct tm_iu *tmp_tmiu; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Remove completed, aborted or failed commands from cmd_queue */ list_for_each_entry_safe(cmdiu, tmp_cmdiu, cmd_queue, node) { - DBG(udev->ucommon->common, "%s() - cmd_queue cycle" + DBG(udev->ucommon, "%s() - cmd_queue cycle" " cmdiu->state=%d " " cmdiu->req_sts=%d\n", __func__, cmdiu->state, cmdiu->req_sts); @@ -757,13 +857,13 @@ static void remove_completed_commands(struct uasp_dev *udev, if (cmdiu->req_sts == CMD_REQ_IN_PROGRESS) continue; } - DBG(udev->ucommon->common, "%s() - deleted cmdiu: " + DBG(udev->ucommon, "%s() - deleted cmdiu: " "cmdiu[0] = %d, cmdiu->state = %d," "cmdiu->tag = %d\n", __func__, cmdiu->cdb[0], cmdiu->state, cmdiu->tag); list_del(&cmdiu->node); if (cmdiu->bh) { - DBG(udev->ucommon->common, "%s() - Freeing the " + DBG(udev->ucommon, "%s() - Freeing the " "cmdiu->bh\n", __func__); cmdiu->bh->state = BUF_STATE_EMPTY; } @@ -778,19 +878,19 @@ static void remove_completed_commands(struct uasp_dev *udev, tmiu->state != COMMAND_STATE_FAILED) continue; - DBG(udev->ucommon->common, "%s() - deleted tmiu\n", __func__); + DBG(udev->ucommon, "%s() - deleted tmiu\n", __func__); list_del(&tmiu->node); if (tmiu->bh) { - DBG(udev->ucommon->common, "%s() - Freeing the " + DBG(udev->ucommon, "%s() - Freeing the " "tmiu->bh\n", __func__); tmiu->bh->state = BUF_STATE_EMPTY; } kfree(tmiu); } if (list_empty(cmd_queue) && list_empty(tm_func_queue)) - DBG(udev->ucommon->common, "%s() - both lists are empty\n", + DBG(udev->ucommon, "%s() - both lists are empty\n", __func__); - DBG(udev->ucommon->common, "%s() - exit\n", __func__); + DBG(udev->ucommon, "%s() - exit\n", __func__); } /** @@ -802,40 +902,36 @@ static void remove_completed_commands(struct uasp_dev *udev, * * Initiates all endpoints and enables them. Allocates buffers and requests. */ -static int do_uasp_set_interface(struct uasp_dev *uaspd, - struct fsg_dev *new_fsg) +static int do_uasp_set_interface(struct uasp_common *ucommon, + struct uasp_dev *new_uaspd) { int rc = 0; int i; - struct fsg_dev *fsgd; - struct fsg_common *fcommon; unsigned long flags; + struct uasp_dev *udev = ucommon->udev; - if (!uaspd || !uaspd->ucommon || !uaspd->ucommon->common) + if (!ucommon) return -EIO; - DBG(uaspd->ucommon->common, "%s()- Enter\n", __func__); + DBG(ucommon, "%s()- Enter\n", __func__); - fcommon = uaspd->ucommon->common; - if (uaspd->ucommon->common->running) - DBG(uaspd->ucommon->common, "reset inteface\n"); + if (ucommon->running) + DBG(ucommon, "reset inteface\n"); reset_uasp: /* Deallocate the requests */ - if (uaspd->ucommon->common->fsg) { - fsgd = fcommon->fsg; - - abort_commands(uaspd, &uaspd->cmd_queue, &uaspd->tm_func_queue, - &(uaspd->ucommon->common->lock)); - remove_completed_commands(uaspd, &uaspd->cmd_queue, - &uaspd->tm_func_queue); - uaspd->pending_requests = 0; - - for (i = 0; i < uaspd->ucommon->common->nluns; i++) { - struct uasp_lun *ulun = &uaspd->ucommon->uluns[i]; - abort_commands(uaspd, &ulun->cmd_queue, + if (ucommon->udev) { + abort_commands(udev, &udev->cmd_queue, + &udev->tm_func_queue, &(udev->ucommon->lock)); + remove_completed_commands(udev, &udev->cmd_queue, + &udev->tm_func_queue); + udev->pending_requests = 0; + + for (i = 0; i < ucommon->nluns; i++) { + struct uasp_lun *ulun = &ucommon->uluns[i]; + abort_commands(udev, &ulun->cmd_queue, &ulun->tm_func_queue, &(ulun->lock)); - remove_completed_commands(uaspd, &ulun->cmd_queue, + remove_completed_commands(udev, &ulun->cmd_queue, &ulun->tm_func_queue); spin_lock_irqsave(&(ulun->lock), flags); ulun->pending_requests = 0; @@ -847,130 +943,142 @@ reset_uasp: spin_unlock_irq(&(ulun->lock)); } /* Clear out the controller's fifos */ - if (fcommon->fsg->bulk_in_enabled) - usb_ep_fifo_flush(fcommon->fsg->bulk_in); - if (fcommon->fsg->bulk_out_enabled) - usb_ep_fifo_flush(fcommon->fsg->bulk_out); - usb_ep_fifo_flush(uaspd->ucommon->udev->status); - usb_ep_fifo_flush(uaspd->ucommon->udev->command); - - spin_lock_irq(&fcommon->lock); + if (udev->bulk_in_enabled) + usb_ep_fifo_flush(udev->bulk_in); + if (udev->bulk_out_enabled) + usb_ep_fifo_flush(udev->bulk_out); + usb_ep_fifo_flush(udev->status); + usb_ep_fifo_flush(udev->command); + + spin_lock_irq(&ucommon->lock); /* Reset the I/O buffer states and pointers */ for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &fcommon->buffhds[i]; + struct fsg_buffhd *bh = + ucommon->ubufs[i].fsg_buff; if (bh->inreq) { - usb_ep_free_request(fsgd->bulk_in, bh->inreq); + usb_ep_free_request(udev->bulk_in, bh->inreq); bh->inreq = NULL; } if (bh->outreq) { - usb_ep_free_request(fsgd->bulk_out, bh->outreq); + usb_ep_free_request(udev->bulk_out, bh->outreq); bh->outreq = NULL; } bh->state = BUF_STATE_EMPTY; } - + spin_unlock_irq(&ucommon->lock); /* Deallocate command and status requests */ - if (uaspd->cmd_buff.inreq) { - ERROR(uaspd->ucommon->common, + if (udev->cmd_buff.inreq) { + ERROR(ucommon, "%s(): uaspd->cmd_buff.inreq isn't NULL. " "How can that be???", __func__); - usb_ep_free_request(uaspd->command, - uaspd->cmd_buff.inreq); - uaspd->cmd_buff.inreq = NULL; + usb_ep_free_request(udev->command, + udev->cmd_buff.inreq); + udev->cmd_buff.inreq = NULL; } - if (uaspd->cmd_buff.outreq) { - usb_ep_free_request(uaspd->command, - uaspd->cmd_buff.outreq); - uaspd->cmd_buff.outreq = NULL; + if (udev->cmd_buff.outreq) { + (void)usb_ep_dequeue(udev->command, + udev->cmd_buff.outreq); + usb_ep_free_request(udev->command, + udev->cmd_buff.outreq); + udev->cmd_buff.outreq = NULL; } - uaspd->cmd_buff.state = BUF_STATE_EMPTY; - spin_unlock_irq(&fcommon->lock); + udev->cmd_buff.state = BUF_STATE_EMPTY; /* Disable the endpoints */ - if (fsgd->bulk_in_enabled) { - usb_ep_disable(fsgd->bulk_in); - fsgd->bulk_in_enabled = 0; + if (udev->bulk_in_enabled) { + usb_ep_disable(udev->bulk_in); + udev->bulk_in_enabled = 0; } - if (fsgd->bulk_out_enabled) { - usb_ep_disable(fsgd->bulk_out); - fsgd->bulk_out_enabled = 0; + if (udev->bulk_out_enabled) { + usb_ep_disable(udev->bulk_out); + udev->bulk_out_enabled = 0; } - fsgd->bulk_in->desc = NULL; - fsgd->bulk_out->desc = NULL; + udev->bulk_in->desc = NULL; + udev->bulk_out->desc = NULL; - if (uaspd->cmd_enabled) { - usb_ep_disable(uaspd->command); - uaspd->cmd_enabled = 0; + if (udev->cmd_enabled) { + usb_ep_disable(udev->command); + udev->cmd_enabled = 0; } - if (uaspd->status_enabled) { - usb_ep_disable(uaspd->status); - uaspd->status_enabled = 0; + if (udev->status_enabled) { + usb_ep_disable(udev->status); + udev->status_enabled = 0; } - uaspd->command->desc = NULL; - uaspd->status->desc = NULL; - DBG(uaspd->ucommon->common, "%s()- disabled endpoints\n", + udev->command->desc = NULL; + udev->status->desc = NULL; + DBG(ucommon, + "%s()- disabled endpoints, releasing config mutex\n", __func__); - - fcommon->fsg = NULL; - wake_up(&fcommon->fsg_wait); + mutex_unlock(ucommon->config_mutex); + ucommon->udev = NULL; + wake_up(&ucommon->uasp_wait); } - fcommon->running = 0; - if (!new_fsg || rc) + ucommon->running = 0; + if (!new_uaspd || rc) { + udev->op_mode = UASP_MODE_UNSET; return rc; + } + DBG(ucommon, "%s()- Enabling endpoints, taking config mutex\n", + __func__); + mutex_lock(ucommon->config_mutex); + ucommon->udev = new_uaspd; + udev = ucommon->udev; + if (!udev->op_mode) { + if (udev->forced_hs_mode) + udev->op_mode = HS_UASP_MODE; + else + udev->op_mode = + (ucommon->gadget->speed == USB_SPEED_SUPER ? + SS_UASP_MODE : HS_UASP_MODE); + } - fcommon->fsg = new_fsg; - fsgd = fcommon->fsg; - uaspd->op_mode = (fcommon->gadget->speed == USB_SPEED_SUPER ? - SS_UASP_MODE : HS_UASP_MODE); - - /* Enable the endpoints */ - config_ep_by_speed(fcommon->gadget, &fsgd->function, fsgd->bulk_in); - rc = usb_ep_enable(fsgd->bulk_in); + config_ep_by_speed(ucommon->gadget, &udev->function, udev->bulk_in); + rc = usb_ep_enable(udev->bulk_in); if (rc) goto reset_uasp; - fsgd->bulk_in->driver_data = uaspd; - fsgd->bulk_in_enabled = 1; + udev->bulk_in->driver_data = udev; + udev->bulk_in_enabled = 1; - config_ep_by_speed(fsgd->common->gadget, &fsgd->function, - fsgd->bulk_out); - rc = usb_ep_enable(fsgd->bulk_out); + config_ep_by_speed(ucommon->gadget, &udev->function, + udev->bulk_out); + rc = usb_ep_enable(udev->bulk_out); if (rc) goto reset_uasp; - fsgd->bulk_out->driver_data = uaspd; - fsgd->bulk_out_enabled = 1; + udev->bulk_out->driver_data = udev; + udev->bulk_out_enabled = 1; - fsgd->common->bulk_out_maxpacket = - le16_to_cpu(fsgd->bulk_out->maxpacket); - clear_bit(IGNORE_BULK_OUT, &fsgd->atomic_bitflags); + /*ucommon->bulk_out_maxpacket = + le16_to_cpu(udev->bulk_out->maxpacket); + clear_bit(IGNORE_BULK_OUT, &fsgd->atomic_bitflags);*/ - config_ep_by_speed(fsgd->common->gadget, &fsgd->function, - uaspd->command); - rc = usb_ep_enable(uaspd->command); + config_ep_by_speed(ucommon->gadget, &udev->function, + udev->command); + rc = usb_ep_enable(udev->command); if (rc) goto reset_uasp; - uaspd->command->driver_data = uaspd; - uaspd->cmd_enabled = 1; + udev->command->driver_data = udev; + udev->cmd_enabled = 1; - config_ep_by_speed(fsgd->common->gadget, &fsgd->function, - uaspd->status); - rc = usb_ep_enable(uaspd->status); + config_ep_by_speed(ucommon->gadget, &udev->function, + udev->status); + rc = usb_ep_enable(udev->status); if (rc) goto reset_uasp; - uaspd->status->driver_data = uaspd; - uaspd->status_enabled = 1; + udev->status->driver_data = udev; + udev->status_enabled = 1; /* Allocate the data - requests */ for (i = 0; i < fsg_num_buffers; ++i) { - struct uasp_buff *buff = &uaspd->ucommon->ubufs[i]; + struct uasp_buff *buff = &ucommon->ubufs[i]; - buff->fsg_buff->inreq = usb_ep_alloc_request(fsgd->bulk_in, + buff->fsg_buff->inreq = usb_ep_alloc_request(udev->bulk_in, GFP_ATOMIC); if (!buff->fsg_buff->inreq) goto reset_uasp; - buff->fsg_buff->outreq = usb_ep_alloc_request(fsgd->bulk_out, + buff->fsg_buff->outreq = usb_ep_alloc_request(udev->bulk_out, GFP_ATOMIC); if (!buff->fsg_buff->outreq) goto reset_uasp; @@ -984,24 +1092,24 @@ reset_uasp: } /* Allocate command ep request */ - uaspd->cmd_buff.outreq = usb_ep_alloc_request(uaspd->command, + udev->cmd_buff.outreq = usb_ep_alloc_request(udev->command, GFP_ATOMIC); - if (!uaspd->cmd_buff.outreq) { - ERROR(uaspd->ucommon->common, "failed allocating outreq for " + if (!udev->cmd_buff.outreq) { + ERROR(ucommon, "failed allocating outreq for " "command buffer\n"); goto reset_uasp; } - DBG(uaspd->ucommon->common, "%s() Enebled endpoints. " + DBG(ucommon, "%s() Enebled endpoints. " "Opperation mode = %d\n", __func__, - uaspd->op_mode); - uaspd->cmd_buff.outreq->buf = &(uaspd->cmd_buff.buf); - uaspd->cmd_buff.inreq = NULL; - uaspd->cmd_buff.state = BUF_STATE_EMPTY; - - fcommon->running = 1; - for (i = 0; i < fsgd->common->nluns; ++i) - fsgd->common->luns[i].unit_attention_data = SS_RESET_OCCURRED; + udev->op_mode); + udev->cmd_buff.outreq->buf = &(udev->cmd_buff.buf); + udev->cmd_buff.inreq = NULL; + udev->cmd_buff.state = BUF_STATE_EMPTY; + + ucommon->running = 1; + for (i = 0; i < ucommon->nluns; ++i) + ucommon->uluns[i].lun->unit_attention_data = SS_RESET_OCCURRED; return 0; } @@ -1011,12 +1119,10 @@ static void handle_uasp_exception(struct uasp_common *ucommon) int sig; int i; struct fsg_buffhd *bh; - enum fsg_state old_state; + enum uasp_state old_state; int rc; - struct fsg_common *fcommon = ucommon->common; - - DBG(ucommon->common, "%s()- Enter\n", __func__); + DBG(ucommon, "%s()- Enter\n", __func__); /* * Clear the existing signals. Anything but SIGUSR1 is converted @@ -1027,9 +1133,9 @@ static void handle_uasp_exception(struct uasp_common *ucommon) if (!sig) break; if (sig != SIGUSR1) { - if (fcommon->state < FSG_STATE_EXIT) - DBG(fcommon, "Main thread exiting on signal\n"); - fcommon->state = FSG_STATE_EXIT; + if (ucommon->state < UASP_STATE_EXIT) + DBG(ucommon, "Main thread exiting on signal\n"); + ucommon->state = UASP_STATE_EXIT; } } @@ -1037,51 +1143,42 @@ static void handle_uasp_exception(struct uasp_common *ucommon) * Reset the I/O buffer states and pointers, the SCSI state, and the * exception. Then invoke the handler. */ - spin_lock_irq(&fcommon->lock); + spin_lock_irq(&ucommon->lock); for (i = 0; i < fsg_num_buffers; ++i) { - bh = &fcommon->buffhds[i]; + bh = ucommon->ubufs[i].fsg_buff; bh->state = BUF_STATE_EMPTY; } - old_state = fcommon->state; - fcommon->state = FSG_STATE_IDLE; - spin_unlock_irq(&fcommon->lock); + old_state = ucommon->state; + ucommon->state = UASP_STATE_IDLE; + spin_unlock_irq(&ucommon->lock); /* Carry out any extra actions required for the exception */ switch (old_state) { - case FSG_STATE_ABORT_BULK_OUT: - case FSG_STATE_RESET: - /* TODO */ - break; - - case FSG_STATE_CONFIG_CHANGE: - if (fcommon->fsg == fcommon->new_fsg) { - DBG(fcommon, "nothing to do. same config\n"); - break; - } + case UASP_STATE_CONFIG_CHANGE: /* Enable/disable the interface according to the new_config */ - rc = do_uasp_set_interface(ucommon->udev, fcommon->new_fsg); + rc = do_uasp_set_interface(ucommon, ucommon->new_udev); if (rc != 0) - fcommon->fsg = NULL; /* Reset on errors */ + ucommon->udev = NULL; /* Reset on errors */ + if (ucommon->new_udev) + usb_composite_setup_continue(ucommon->cdev); break; - case FSG_STATE_EXIT: - case FSG_STATE_TERMINATED: + case UASP_STATE_EXIT: + case UASP_STATE_TERMINATED: /* Free resources */ - (void)do_uasp_set_interface(ucommon->udev, NULL); - spin_lock_irq(&fcommon->lock); - fcommon->state = FSG_STATE_TERMINATED; /* Stop the thread*/ - spin_unlock_irq(&fcommon->lock); + (void)do_uasp_set_interface(ucommon, NULL); + spin_lock_irq(&ucommon->lock); + ucommon->state = UASP_STATE_TERMINATED; /* Stop the thread*/ + spin_unlock_irq(&ucommon->lock); break; - case FSG_STATE_INTERFACE_CHANGE: - case FSG_STATE_DISCONNECT: - case FSG_STATE_COMMAND_PHASE: - case FSG_STATE_DATA_PHASE: - case FSG_STATE_STATUS_PHASE: - case FSG_STATE_IDLE: + case UASP_STATE_INTERFACE_CHANGE: + case UASP_STATE_DISCONNECT: + case UASP_STATE_RESET: + case UASP_STATE_IDLE: break; } - DBG(ucommon->common, "%s()- Exit\n", __func__); + DBG(ucommon, "%s()- Exit\n", __func__); } /** @@ -1121,7 +1218,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) req = udev->cmd_buff.outreq; *command = NULL; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Id of the received command (tmiu or cmdiu) */ cmd_id = ((uint8_t *)req->buf)[0]; @@ -1131,7 +1228,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Invalid completion status */ if (req->status) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Invalid completion status for command " "request = -%d\n", __func__, req->status); return -EINVAL; @@ -1139,7 +1236,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Check is the data received via command endpoint is a command */ if (cmd_id != IU_ID_TASK_MANAGEMENT && cmd_id != IU_ID_COMMAND) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Invalid data is received\n", __func__); /* TODO: something needs to be done (e.g. halt endpoints) */ return -EINVAL; @@ -1147,7 +1244,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Invalid count of bytes received for tmiu */ if (cmd_id == IU_ID_TASK_MANAGEMENT && req->actual != 16) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Invalid byte count for tmiu is received = %d\n", __func__, req->actual); /* TODO: something needs to be done (e.g. halt endpoints) */ @@ -1156,7 +1253,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Invalid count of bytes received for cmdiu */ if (cmd_id == IU_ID_COMMAND && req->actual < 32) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Invalid byte count for cmdiu is received = %d\n", __func__, req->actual); /* TODO: something needs to be done (e.g. halt endpoints) */ @@ -1171,7 +1268,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) tmiu = kmalloc(sizeof(struct tm_iu), GFP_KERNEL); if (!tmiu) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - No memory for tmiu\n", __func__); return -ENOMEM; } @@ -1181,7 +1278,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) cmdiu = kmalloc(sizeof(struct cmd_iu), GFP_KERNEL); if (!cmdiu) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - No memory for cmdiu\n", __func__); return -ENOMEM; } @@ -1191,7 +1288,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Check for overlapping tag */ /* Check for tag overlapping over all cmd an tm_func queues */ - for (i = 0; i < udev->ucommon->common->nluns; ++i) { + for (i = 0; i < udev->ucommon->nluns; ++i) { curlun = &udev->ucommon->uluns[i]; spin_lock_irqsave(&(curlun->lock), flags); @@ -1221,7 +1318,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) spin_unlock_irqrestore(&(curlun->lock), flags); } - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); list_for_each_entry(tmp_cmdiu, &udev->cmd_queue, node) { if (tmp_cmdiu->state != COMMAND_STATE_IDLE && tmp_cmdiu->state != COMMAND_STATE_DATA && @@ -1231,7 +1328,7 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Overlapped tag found */ if (tmp_cmdiu->tag == tag) { - spin_unlock_irqrestore(&(udev->ucommon->common->lock), + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); goto overlapped_tag; } @@ -1244,12 +1341,12 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) /* Overlapped tag found */ if (tmp_tmiu->tag == tag) { - spin_unlock_irqrestore(&(udev->ucommon->common->lock), + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); goto overlapped_tag; } } - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); /* No overlapped tag */ if (cmd_id == IU_ID_TASK_MANAGEMENT) @@ -1258,42 +1355,43 @@ static int uasp_command_check(struct uasp_dev *udev, void **command) return 1; overlapped_tag: - ERROR(udev->ucommon->common, "%s() - Overlapped tag found. " + ERROR(udev->ucommon, "%s() - Overlapped tag found. " "Aborting all\n", __func__); run_lun_threads(udev, LUN_STATE_OVERLAPPED_TAG); /* Wait for luns abort completion. Sleep if luns are in processing */ while (!all_lun_state_non_processing(udev)) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - Luns are in process. Going to sleep\n", __func__); - rc = sleep_thread(udev->ucommon->common); + rc = uasp_sleep_thread(udev->ucommon); if (rc) { - ERROR(udev->ucommon->common, - "%s() - sleep_thread failed! (%d)", __func__, rc); + ERROR(udev->ucommon, + "%s() - uasp_sleep_thread failed! (%d)", + __func__, rc); return -EINVAL; } - DBG(udev->ucommon->common, "%s() - Wakes up\n", __func__); + DBG(udev->ucommon, "%s() - Wakes up\n", __func__); rc = 0; } /* Abort none-lun commands */ abort_commands(udev, &udev->cmd_queue, &udev->tm_func_queue, - &(udev->ucommon->common->lock)); + &(udev->ucommon->lock)); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); udev->pending_requests = 0; - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); if (cmd_id == IU_ID_TASK_MANAGEMENT) { tmiu = *command; - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); - tmiu->bh = get_buffhd(udev->ucommon->common->buffhds); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); + tmiu->bh = get_buffhd(udev->ucommon->ubufs); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); if (!tmiu->bh) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s(): didnt manage to get buffers for tmiu!\n", __func__); return -EINVAL; @@ -1317,12 +1415,12 @@ overlapped_tag: } else { cmdiu = *command; - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); - cmdiu->bh = get_buffhd(udev->ucommon->common->buffhds); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); + cmdiu->bh = get_buffhd(udev->ucommon->ubufs); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); if (!cmdiu->bh) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s(): didnt manage to get buffers for cmdiu!\n", __func__); return -EINVAL; @@ -1364,7 +1462,7 @@ static void insert_tm_func_to_list(struct uasp_dev *udev, struct tm_iu *tmiu) struct tm_iu *tmiu1; struct uasp_lun *curlun; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); curlun = find_lun_by_id(udev, tmiu->lun); tmiu->state = COMMAND_STATE_IDLE; @@ -1449,10 +1547,10 @@ static void insert_cmd_to_list(struct uasp_dev *udev, struct cmd_iu *cmdiu) struct cmd_iu *cmdiu1; struct uasp_lun *curlun; - DBG(udev->ucommon->common, "%s(): cmdiu->lun = %p\n", __func__, + DBG(udev->ucommon, "%s(): cmdiu->lun = %p\n", __func__, cmdiu->lun); - DBG(udev->ucommon->common, "%02x %02x %02x %02x %02x %02x %02x %02x\n", + DBG(udev->ucommon, "%02x %02x %02x %02x %02x %02x %02x %02x\n", cmdiu->lun[0], cmdiu->lun[1], cmdiu->lun[2], cmdiu->lun[3], cmdiu->lun[4], cmdiu->lun[5], cmdiu->lun[6], cmdiu->lun[7]); @@ -1489,7 +1587,7 @@ static void insert_cmd_to_list(struct uasp_dev *udev, struct cmd_iu *cmdiu) /* In the case when the queue is empty */ list_add_tail(&cmdiu->node, link); - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - Cmdiu is added to the tail of the queue\n", __func__); } @@ -1510,7 +1608,7 @@ static int get_command(struct uasp_dev *udev) int rc = 0; void *command = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); queue_cmd_ep: /* If command endpoint is not active, activate */ @@ -1525,11 +1623,11 @@ queue_cmd_ep: udev->cmd_buff.outreq->short_not_ok = 1; rc = usb_ep_queue(udev->command, udev->cmd_buff.outreq, 0); if (rc) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s()usb_ep_queue failed = %d\n", __func__, rc); udev->cmd_buff.state = BUF_STATE_EMPTY; } - DBG(udev->ucommon->common, "%s() queued command request = %p\n", + DBG(udev->ucommon, "%s() queued command request = %p\n", __func__, udev->cmd_buff.outreq); return rc; } @@ -1540,13 +1638,13 @@ queue_cmd_ep: rc = uasp_command_check(udev, &command); if (rc == 0) { - DBG(udev->ucommon->common, "%s() - Received a TMC IU\n", + DBG(udev->ucommon, "%s() - Received a TMC IU\n", __func__); insert_tm_func_to_list(udev, (struct tm_iu *)command); udev->cmd_buff.state = BUF_STATE_EMPTY; goto queue_cmd_ep; } else if (rc == 1) { - DBG(udev->ucommon->common, "%s() -Received a CMD IU\n", + DBG(udev->ucommon, "%s() -Received a CMD IU\n", __func__); insert_cmd_to_list(udev, (struct cmd_iu *)command); udev->cmd_buff.state = BUF_STATE_EMPTY; @@ -1567,9 +1665,9 @@ int all_lun_state_non_processing(struct uasp_dev *udev) struct uasp_lun *curlun; int i; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); - for (i = 0; i < udev->ucommon->common->nluns; ++i) { + for (i = 0; i < udev->ucommon->nluns; ++i) { curlun = &udev->ucommon->uluns[i]; if (curlun->lun_state > LUN_STATE_IDLE) return 0; @@ -1590,8 +1688,8 @@ static int pending_cmd_in_lun(void *data) struct uasp_lun *curlun; int i; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); - for (i = 0; i < udev->ucommon->common->nluns; ++i) { + DBG(udev->ucommon, "%s() - Enter\n", __func__); + for (i = 0; i < udev->ucommon->nluns; ++i) { curlun = &udev->ucommon->uluns[i]; if (curlun->pending_requests) return 1; @@ -1633,17 +1731,17 @@ void run_lun_threads(struct uasp_dev *udev, int state) int i; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter. State = %d\n", + DBG(udev->ucommon, "%s() - Enter. State = %d\n", __func__, state); - for (i = 0; i < udev->ucommon->common->nluns; ++i) { + for (i = 0; i < udev->ucommon->nluns; ++i) { curlun = &udev->ucommon->uluns[i]; spin_lock_irqsave(&(curlun->lock), flags); curlun->lun_state = state; wakeup_lun_thread(curlun); spin_unlock_irqrestore(&(curlun->lock), flags); } - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); } /** @@ -1667,7 +1765,7 @@ void abort_commands(struct uasp_dev *udev, struct cmd_iu *cmdiu, *tmp_cmdiu; struct tm_iu *tmiu, *tmp_tmiu; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (!cmd_queue) goto tmiu_part; @@ -1732,58 +1830,47 @@ tmiu_part: void do_uasp(struct uasp_dev *udev) { unsigned long flags; - struct fsg_dev *fsg = &(udev->fsg_dev); struct uasp_common *ucommon = udev->ucommon; int rc; - DBG(ucommon->common, "%s() - Enter\n", __func__); - - spin_lock_irqsave(&(fsg->common->lock), flags); - if (!exception_in_progress(fsg->common)) - fsg->common->state = FSG_STATE_COMMAND_PHASE; - spin_unlock_irqrestore(&(fsg->common->lock), flags); + DBG(ucommon, "%s() - Enter\n", __func__); - if (exception_in_progress(fsg->common)) + if (uasp_exception_in_progress(ucommon)) return; if (get_command(udev)) return; - spin_lock_irqsave(&(fsg->common->lock), flags); - if (!exception_in_progress(fsg->common)) - fsg->common->state = FSG_STATE_DATA_PHASE; - spin_unlock_irqrestore(&(fsg->common->lock), flags); - - if (exception_in_progress(fsg->common)) + if (uasp_exception_in_progress(ucommon)) return; - spin_lock_irqsave(&(ucommon->common->lock), flags); + spin_lock_irqsave(&(ucommon->lock), flags); udev->pending_requests = 0; - spin_unlock_irqrestore(&(ucommon->common->lock), flags); + spin_unlock_irqrestore(&(ucommon->lock), flags); do_tmiu(udev, NULL); - if (exception_in_progress(fsg->common)) + if (uasp_exception_in_progress(ucommon)) return; do_cmdiu(udev, NULL); - if (exception_in_progress(fsg->common)) + if (uasp_exception_in_progress(ucommon)) return; remove_completed_commands(udev, &udev->cmd_queue, &udev->tm_func_queue); - spin_lock_irqsave(&(fsg->common->lock), flags); - if (!exception_in_progress(fsg->common)) { - fsg->common->state = FSG_STATE_IDLE; - spin_unlock_irqrestore(&(fsg->common->lock), flags); + spin_lock_irqsave(&(ucommon->lock), flags); + if (!uasp_exception_in_progress(ucommon)) { + ucommon->state = UASP_STATE_IDLE; + spin_unlock_irqrestore(&(ucommon->lock), flags); run_lun_threads(udev, LUN_STATE_PROCESSING); } else - spin_unlock_irqrestore(&(fsg->common->lock), flags); + spin_unlock_irqrestore(&(ucommon->lock), flags); rc = 0; while (!rc) { /* If exception is in progress */ - if (exception_in_progress(ucommon->common)) { - DBG(ucommon->common, + if (uasp_exception_in_progress(ucommon)) { + DBG(ucommon, "%s() - Exception is in progress\n", __func__); return; } @@ -1791,39 +1878,39 @@ void do_uasp(struct uasp_dev *udev) /* Sleep if luns are in processing */ rc = all_lun_state_non_processing(udev); if (!rc) { - DBG(ucommon->common, + DBG(ucommon, "%s() - Luns are in process\n", __func__); goto sleep; } /* Wake up if command is received */ if (udev->cmd_buff.state == BUF_STATE_FULL) { - DBG(ucommon->common, + DBG(ucommon, "%s() - Command is received\n", __func__); return; } /* Wake up if there are pending requests in luns */ if (pending_cmd_in_lun(udev)) { - DBG(ucommon->common, + DBG(ucommon, "%s() - Pending requests in LUN\n", __func__); return; } /* Wake up if there are pending requests */ if (udev->pending_requests) { - DBG(ucommon->common, + DBG(ucommon, "%s() - Pending requests in device\n", __func__); return; } sleep: /* Try to sleep */ - DBG(ucommon->common, "%s() - Going to sleep\n", __func__); - rc = sleep_thread(fsg->common); + DBG(ucommon, "%s() - Going to sleep\n", __func__); + rc = uasp_sleep_thread(ucommon); if (rc) return; - DBG(ucommon->common, "%s() - Wakes up\n", __func__); + DBG(ucommon, "%s() - Wakes up\n", __func__); rc = 0; } @@ -1867,7 +1954,7 @@ static int lun_exception_in_progress(struct uasp_lun *curlun) static void handle_lun_exception(struct uasp_dev *udev, struct uasp_lun *curlun) { unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Abort all commands and remove them from lists */ abort_commands(udev, &curlun->cmd_queue, &curlun->tm_func_queue, @@ -1890,7 +1977,7 @@ static void handle_lun_exception(struct uasp_dev *udev, struct uasp_lun *curlun) break; } spin_unlock_irqrestore(&(curlun->lock), flags); - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); } /** @@ -1915,15 +2002,15 @@ static int uasp_lun_thread(void *param) if (!ulun) return -1; udev = ulun->dev; - DBG(udev->ucommon->common, "%s() - Enter for lun_id = %d\n", __func__, + DBG(udev->ucommon, "%s() - Enter for lun_id = %d\n", __func__, ulun->lun_id[7]); while (ulun->lun_state != LUN_STATE_TERMINATED) { - DBG(udev->ucommon->common, "%s() - Wakes up\n", __func__); + DBG(udev->ucommon, "%s() - Wakes up\n", __func__); if (lun_exception_in_progress(ulun)) { - DBG(udev->ucommon->common, - "%s() - exception_in_progress!" + DBG(udev->ucommon, + "%s() - uasp_exception_in_progress!" " ulun->lun_state=%d\n", __func__, ulun->lun_state); handle_lun_exception(udev, ulun); @@ -1934,8 +2021,8 @@ static int uasp_lun_thread(void *param) * If the main thread isn't running, no need to run lun threads * as well. */ - if (!udev->ucommon->common->running) { - DBG(udev->ucommon->common, + if (!udev->ucommon->running) { + DBG(udev->ucommon, "%s() - uasp thread main thread not running - " "going to sleep...\n", __func__); sleep_lun_thread(ulun); @@ -1959,22 +2046,22 @@ static int uasp_lun_thread(void *param) if (lun_exception_in_progress(ulun)) continue; - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); if (!lun_exception_in_progress(ulun)) { ulun->lun_state = LUN_STATE_IDLE; - wakeup_thread(udev->ucommon->common); + uasp_wakeup_thread(udev->ucommon); } - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); - DBG(udev->ucommon->common, "%s() - Going to sleep\n", __func__); + DBG(udev->ucommon, "%s() - Going to sleep\n", __func__); sleep_lun_thread(ulun); continue; } - DBG(udev->ucommon->common, "uasp lun main loop: exiting\n"); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + DBG(udev->ucommon, "uasp lun main loop: exiting\n"); + spin_lock_irqsave(&(udev->ucommon->lock), flags); ulun->lun_thread_task = NULL; - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); /* Let the unbind and cleanup routines know the thread has exited */ complete_and_exit(&ulun->thread_notifier, 0); return 0; @@ -1993,8 +2080,6 @@ static int uasp_lun_thread(void *param) static int uasp_main_thread(void *param) { struct uasp_common *ucommon = (struct uasp_common *)param; - struct fsg_common *common = ucommon->common; - /* * Allow the thread to be killed by a signal, but set the signal mask * to block everything but INT, TERM, KILL, and USR1. @@ -2015,41 +2100,41 @@ static int uasp_main_thread(void *param) set_fs(get_ds()); /* The main loop */ - while (common->state != FSG_STATE_TERMINATED) { - DBG(common, "uasp main loop: continuing\n"); - if (exception_in_progress(ucommon->common) || + while (ucommon->state != UASP_STATE_TERMINATED) { + DBG(ucommon, "uasp main loop: continuing\n"); + if (uasp_exception_in_progress(ucommon) || signal_pending(current)) { - DBG(common, "uasp thread main loop: exception\n"); + DBG(ucommon, "uasp thread main loop: exception\n"); handle_uasp_exception(ucommon); continue; } - if (!common->running) { - DBG(common, "uasp thread main loop: not running\n"); - sleep_thread(ucommon->common); + if (!ucommon->running) { + DBG(ucommon, "uasp thread main loop: not running\n"); + uasp_sleep_thread(ucommon); continue; } do_uasp(ucommon->udev); } - DBG(common, "uasp main loop: exiting\n"); + DBG(ucommon, "uasp main loop: exiting\n"); - spin_lock_irq(&common->lock); - common->thread_task = NULL; - spin_unlock_irq(&common->lock); + spin_lock_irq(&ucommon->lock); + ucommon->thread_task = NULL; + spin_unlock_irq(&ucommon->lock); - if (!common->ops || !common->ops->thread_exits || - common->ops->thread_exits(common) < 0) { + if (!ucommon->ops || !ucommon->ops->thread_exits || + ucommon->ops->thread_exits(ucommon) < 0) { struct uasp_lun *ulun = ucommon->uluns; unsigned i ; - down_write(&common->filesem); - for (i = 0; i < common->nluns; i++, ulun++) + down_write(&ucommon->filesem); + for (i = 0; i < ucommon->nluns; i++, ulun++) close_lun(ulun); - up_write(&common->filesem); + up_write(&ucommon->filesem); } /* Let the unbind and cleanup routines know the thread has exited */ - complete_and_exit(&common->thread_notifier, 0); + complete_and_exit(&ucommon->thread_notifier, 0); return 0; } @@ -2063,74 +2148,107 @@ static int uasp_main_thread(void *param) * This function should be called after (struct fsg_common) common was already * initiated by fsg_common_init */ -static struct uasp_common *uasp_common_init(struct fsg_common *common, - struct usb_composite_dev *cdev, - struct fsg_config *cfg) +static struct uasp_common *uasp_common_init(struct msg_common_data *common, + struct usb_composite_dev *cdev) { struct fsg_lun *flun; struct uasp_lun *ulun; struct uasp_common *ucommon; - int nluns = common->nluns; - int i, rc; + int i, rc = 0; - if (!common || !cdev || !cfg) + if (!common || !cdev) return NULL; - DBG(common, "%s() - Enter\n", __func__); + DBG(cdev, "%s() - Enter\n", __func__); ucommon = kzalloc(sizeof *ucommon, GFP_KERNEL); if (unlikely(!ucommon)) return NULL; - /* Save reference to fsg_common structure in ucommon */ - ucommon->common = common; - - /* Allocate the uLUNs and init them according to fsg_common luns */ - ulun = kzalloc(nluns * sizeof *ulun, GFP_KERNEL); + ucommon->msg_common = common; + /*Allocate the uLUNs and init them according to fsg_common luns */ + ulun = kzalloc(common->config.nluns * sizeof *ulun, GFP_KERNEL); if (!ulun) { kfree(ucommon); return ERR_PTR(-ENOMEM); } ucommon->uluns = ulun; + ucommon->nluns = common->config.nluns; /* Create the reference between ulun and fsg_lun */ - for (i = 0, flun = common->luns; i < nluns; + for (i = 0, flun = common->fcommon->luns; i < common->config.nluns; ++i, ++flun, ++ulun) ulun->lun = flun; + ucommon->ops = common->config.uasp_ops; + ucommon->gadget = cdev->gadget; + ucommon->cdev = cdev; + ucommon->config_mutex = &(common->config.config_mutex); + /* - * Buffers in ubufs are static -- no need for additional allocation. - * Connect each ubuf to fsg_buff from the buffhds cyclic list + * Allocate the buffers in ubufs and connect each ubuf to fsg_buff + * from the buffhds cyclic list */ + ucommon->ubufs = kzalloc(sizeof(struct uasp_buff)*fsg_num_buffers, + GFP_KERNEL); + if (!ucommon->ubufs) + goto error_release; + for (i = 0; i < fsg_num_buffers; i++) { - ucommon->ubufs[i].fsg_buff = &(common->buffhds[i]); + ucommon->ubufs[i].fsg_buff = &(common->fcommon->buffhds[i]); ucommon->ubufs[i].ep = NULL; ucommon->ubufs[i].stream_id = 0; } - kref_init(&ucommon->ref); + /* Prepare inquiryString */ + if (common->config.release != 0xffff) { + i = common->config.release; + } else { + i = usb_gadget_controller_number(cdev->gadget); + if (i >= 0) { + i = 0x0300 + i; + } else { + WARNING(ucommon, "controller '%s' not recognized\n", + cdev->gadget->name); + i = 0x0399; + } + } + snprintf(ucommon->inquiry_string, sizeof ucommon->inquiry_string, + "%-8s%-16s%04x", common->config.vendor_name ?: "Linux", + /* Assume product name dependent on the first LUN */ + common->config.product_name ?: (common->fcommon->luns->cdrom + ? "File-Stor UAS-Gadget" + : "File-CD UAS-Gadget"), + i); + /* Tell the thread to start working */ - common->thread_task = + ucommon->thread_task = kthread_create(uasp_main_thread, (void *)ucommon, - cfg->thread_name ?: "file-storage-UASP"); - if (IS_ERR(common->thread_task)) { - rc = PTR_ERR(common->thread_task); + common->config.thread_name ?: + "file-storage-UASP"); + if (IS_ERR(ucommon->thread_task)) { + rc = PTR_ERR(ucommon->thread_task); goto error_release; } /* Information */ - INFO(common, UASP_DRIVER_DESC ", version: " UASP_DRIVER_VERSION "\n"); - DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task)); + INFO(ucommon, UASP_DRIVER_DESC ", version: " UASP_DRIVER_VERSION "\n"); + DBG(ucommon, "I/O thread pid: %d created for UASP Gdaget\n", + task_pid_nr(ucommon->thread_task)); + + kref_init(&ucommon->ref); + init_waitqueue_head(&ucommon->uasp_wait); + init_completion(&ucommon->thread_notifier); - wake_up_process(common->thread_task); + wake_up_process(ucommon->thread_task); return ucommon; error_release: - common->state = FSG_STATE_TERMINATED; /* The thread is dead */ + ucommon->state = UASP_STATE_TERMINATED; /* The thread is dead */ /* Call uasp_common_release() directly, ref might be not initialised */ - uasp_common_release(&common->ref); + uasp_common_release(&ucommon->ref); return ERR_PTR(rc); } @@ -2151,7 +2269,7 @@ static int finish_lun_init(struct uasp_dev *udev) return -EIO; for (i = 0, ulun = udev->ucommon->uluns; - i < udev->ucommon->common->nluns; i++, ulun++) { + i < udev->ucommon->nluns; i++, ulun++) { /* TODO: this is a workaround, fix later */ memset(ulun->lun_id, 0, 8); ulun->lun_id[0] = i; @@ -2163,8 +2281,8 @@ static int finish_lun_init(struct uasp_dev *udev) /* Create and start lun threads */ sprintf(thread_name, "uasp-lun-thread%d", i); - DBG(udev->ucommon->common, - "creating & starting lun thread: thread_name = %s\n", + DBG(udev->ucommon, + "creating lun thread: thread_name = %s\n", thread_name); ulun->lun_thread_task = kthread_create(uasp_lun_thread, @@ -2177,7 +2295,6 @@ static int finish_lun_init(struct uasp_dev *udev) init_completion(&ulun->thread_notifier); wake_up_process(ulun->lun_thread_task); } - INFO(udev->ucommon->common, "All lun threads are started\n"); return rc; err_lun_init: @@ -2193,71 +2310,110 @@ err_lun_init: * * Return 0 on succeed, error code on failure * - * TODO: Add fall back to usb_ep_autoconfig() if usb_ep_autoconfig_ss() fails. - * In that case mark somehow that we can only operate in HS mode */ static int __init uasp_bind(struct usb_configuration *c, struct usb_function *f) { struct uasp_dev *uaspd = uaspd_from_func(f); - struct fsg_dev *fsgd = &(uaspd->fsg_dev); struct usb_gadget *gadget = c->cdev->gadget; int rc; int i; + int hs_mode = 0; struct usb_ep *ep; - fsgd->common->gadget = gadget; + uaspd->ucommon->gadget = gadget; /* Allocate new interface */ i = usb_interface_id(c, f); if (i < 0) return i; uasp_intf_desc.bInterfaceNumber = i; - fsgd->interface_number = i; - /* Find all the endpoints we will use */ - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bulk_in_desc, - &uasp_bulk_in_ep_comp_desc); - if (!ep) - goto autoconf_fail; + if (gadget_is_superspeed(c->cdev->gadget)) { + ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bulk_in_desc, + &uasp_bulk_in_ep_comp_desc); + if (!ep) { + ERROR(uaspd->ucommon, + "%s(): Unable to autoconfigure endpoints" + " in SS mode. Falling back to HS mode...\n", + __func__); + goto fall_back_to_hs; + } + } else { +fall_back_to_hs: + hs_mode = 1; + uaspd->op_mode = HS_UASP_MODE; + uaspd->forced_hs_mode = 1; + ep = usb_ep_autoconfig(gadget, &uasp_fs_bulk_in_desc); + if (!ep) + goto autoconf_fail; + } ep->driver_data = uaspd; /* claim the endpoint */ - fsgd->bulk_in = ep; + uaspd->bulk_in = ep; - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bulk_out_desc, + if (hs_mode) + ep = usb_ep_autoconfig(gadget, &uasp_fs_bulk_out_desc); + else + ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bulk_out_desc, &uasp_bulk_out_ep_comp_desc); if (!ep) goto autoconf_fail; ep->driver_data = uaspd; /* claim the endpoint */ - fsgd->bulk_out = ep; + uaspd->bulk_out = ep; - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_in_desc, + if (hs_mode) + ep = usb_ep_autoconfig(gadget, &uasp_fs_status_in_desc); + else + ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_in_desc, &uasp_status_in_ep_comp_desc); if (!ep) goto autoconf_fail; ep->driver_data = uaspd; /* claim the endpoint */ uaspd->status = ep; - ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_command_out_desc, + if (hs_mode) + ep = usb_ep_autoconfig(gadget, &uasp_fs_command_out_desc); + else + ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_command_out_desc, &uasp_command_out_ep_comp_desc); if (!ep) goto autoconf_fail; ep->driver_data = uaspd; /* claim the endpoint */ uaspd->command = ep; - /* Assume endpoint addresses are the same for both speeds */ - uasp_bulk_in_desc.bEndpointAddress = - uasp_ss_bulk_in_desc.bEndpointAddress; - uasp_bulk_out_desc.bEndpointAddress = - uasp_ss_bulk_out_desc.bEndpointAddress; - uasp_status_in_desc.bEndpointAddress = - uasp_ss_status_in_desc.bEndpointAddress; - uasp_command_out_desc.bEndpointAddress = - uasp_ss_command_out_desc.bEndpointAddress; - f->ss_descriptors = uasp_ss_function_desc; + if (hs_mode) { + if (gadget_is_dualspeed(c->cdev->gadget)) { + uasp_hs_bulk_in_desc.bEndpointAddress = + uasp_fs_bulk_in_desc.bEndpointAddress; + uasp_hs_bulk_out_desc.bEndpointAddress = + uasp_fs_bulk_out_desc.bEndpointAddress; + uasp_hs_status_in_desc.bEndpointAddress = + uasp_fs_status_in_desc.bEndpointAddress; + uasp_hs_command_out_desc.bEndpointAddress = + uasp_fs_command_out_desc.bEndpointAddress; + } + } else { /* SuperSpeed configuration sucseeded */ + uasp_fs_bulk_in_desc.bEndpointAddress = + uasp_ss_bulk_in_desc.bEndpointAddress; + uasp_hs_bulk_in_desc.bEndpointAddress = + uasp_ss_bulk_in_desc.bEndpointAddress; + uasp_fs_bulk_out_desc.bEndpointAddress = + uasp_ss_bulk_out_desc.bEndpointAddress; + uasp_hs_bulk_out_desc.bEndpointAddress = + uasp_ss_bulk_out_desc.bEndpointAddress; + uasp_fs_status_in_desc.bEndpointAddress = + uasp_ss_status_in_desc.bEndpointAddress; + uasp_hs_status_in_desc.bEndpointAddress = + uasp_ss_status_in_desc.bEndpointAddress; + uasp_fs_command_out_desc.bEndpointAddress = + uasp_ss_command_out_desc.bEndpointAddress; + uasp_hs_command_out_desc.bEndpointAddress = + uasp_ss_command_out_desc.bEndpointAddress; + } return 0; autoconf_fail: - ERROR(fsgd->common, "unable to autoconfigure all endpoints\n"); + ERROR(uaspd->ucommon, "unable to autoconfigure all endpoints\n"); rc = -ENOTSUPP; return rc; } @@ -2265,14 +2421,28 @@ autoconf_fail: static void uasp_unbind(struct usb_configuration *c, struct usb_function *f) { struct uasp_dev *uaspd = uaspd_from_func(f); + struct uasp_lun *ulun; + int i; + + DBG(uaspd->ucommon, "%s() - Enter\n", __func__); - DBG(uaspd->fsg_dev.common, "unbind\n"); - if (uaspd->fsg_dev.common->fsg == &(uaspd->fsg_dev)) { - uaspd->fsg_dev.common->new_fsg = NULL; - raise_exception(uaspd->fsg_dev.common, FSG_STATE_CONFIG_CHANGE); + /* First stop all lun threads */ + run_lun_threads(uaspd, LUN_STATE_EXIT); + for (i = 0; i < uaspd->ucommon->nluns; i++) { + ulun = &(uaspd->ucommon->uluns[i]); + if (ulun->lun_state != LUN_STATE_TERMINATED) { + wait_for_completion(&ulun->thread_notifier); + /* The cleanup routine waits for this completion also */ + complete(&ulun->thread_notifier); + } + } + + DBG(uaspd->ucommon, "%s(): Stoped all LUN threads\n", __func__); + if (uaspd->ucommon->udev) { + uaspd->ucommon->new_udev = NULL; + uasp_raise_exception(uaspd->ucommon, UASP_STATE_CONFIG_CHANGE); /* TODO: make interruptible or killable somehow? */ - wait_event(uaspd->fsg_dev.common->fsg_wait, - !uaspd->ucommon->common->fsg); + wait_event(uaspd->ucommon->uasp_wait, !uaspd->ucommon->udev); } uasp_common_put(uaspd->ucommon); kfree(uaspd->cmd_buff.buf); @@ -2281,18 +2451,32 @@ static void uasp_unbind(struct usb_configuration *c, struct usb_function *f) static int uasp_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { - struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->new_fsg = fsg; - raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); - return 0; + struct uasp_dev *udev = uaspd_from_func(f); + int i; + + if (!udev->ucommon->udev) { + struct uasp_lun *ulun; + DBG(udev->ucommon, + "%s() - Waking up UASP main thread\n", __func__); + wake_up_process(udev->ucommon->thread_task); + + /* Wakeup LUN threads */ + for (i = 0, ulun = udev->ucommon->uluns; + i < udev->ucommon->nluns; i++, ulun++) + wake_up_process(ulun->lun_thread_task); + INFO(udev->ucommon, "All lun threads are started\n"); + } + udev->ucommon->new_udev = udev; + uasp_raise_exception(udev->ucommon, UASP_STATE_CONFIG_CHANGE); + return USB_GADGET_DELAYED_STATUS; } static void uasp_disable(struct usb_function *f) { struct uasp_dev *udev = uaspd_from_func(f); - udev->fsg_dev.common->new_fsg = NULL; - raise_exception(udev->fsg_dev.common, FSG_STATE_CONFIG_CHANGE); + udev->ucommon->new_udev = NULL; + uasp_raise_exception(udev->ucommon, UASP_STATE_CONFIG_CHANGE); } /** @@ -2309,7 +2493,6 @@ static void uasp_disable(struct usb_function *f) */ static int uasp_add(struct usb_composite_dev *cdev, struct usb_configuration *c, - struct fsg_common *common, struct uasp_common *ucommon) { struct uasp_dev *uaspd; @@ -2319,18 +2502,17 @@ static int uasp_add(struct usb_composite_dev *cdev, if (unlikely(!uaspd)) return -ENOMEM; - uaspd->fsg_dev.function.name = UASP_DRIVER_DESC; - uaspd->fsg_dev.function.strings = fsg_strings_array; - uaspd->fsg_dev.function.descriptors = uasp_hs_function_desc; - uaspd->fsg_dev.function.hs_descriptors = uasp_hs_function_desc; - uaspd->fsg_dev.function.bind = uasp_bind; - uaspd->fsg_dev.function.unbind = uasp_unbind; - uaspd->fsg_dev.function.set_alt = uasp_set_alt; - uaspd->fsg_dev.function.disable = uasp_disable; - - uaspd->fsg_dev.common = common; + uaspd->function.name = UASP_DRIVER_DESC; + uaspd->function.strings = fsg_strings_array; + uaspd->function.descriptors = uasp_fs_function_desc; + uaspd->function.hs_descriptors = uasp_hs_function_desc; + uaspd->function.ss_descriptors = uasp_ss_function_desc; + uaspd->function.bind = uasp_bind; + uaspd->function.unbind = uasp_unbind; + uaspd->function.set_alt = uasp_set_alt; + uaspd->function.disable = uasp_disable; - uaspd->ucommon = ucommon; + uaspd->ucommon = ucommon; /* Init the command and status buffers */ uaspd->cmd_buff.buf = kmalloc(FSG_BUFLEN, GFP_KERNEL); @@ -2339,7 +2521,6 @@ static int uasp_add(struct usb_composite_dev *cdev, goto uasp_add_err; } - ucommon->udev = uaspd; rc = finish_lun_init(uaspd); if (rc) goto uasp_add_err; @@ -2353,7 +2534,7 @@ static int uasp_add(struct usb_composite_dev *cdev, * recovery we increment it only when call to usb_add_function() was * successful. */ - rc = usb_add_function(c, &uaspd->fsg_dev.function); + rc = usb_add_function(c, &uaspd->function); if (likely(rc == 0)) kref_get(&ucommon->ref); diff --git a/drivers/usb/gadget/f_uasp.h b/drivers/usb/gadget/f_uasp.h index 63ade00..3f1e042 100644 --- a/drivers/usb/gadget/f_uasp.h +++ b/drivers/usb/gadget/f_uasp.h @@ -18,6 +18,15 @@ #define _F_UASP_H #include <linux/kernel.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/completion.h> +#include <linux/kref.h> +#include <linux/kthread.h> +#include <linux/rwsem.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> @@ -79,30 +88,80 @@ struct uasp_buff { unsigned stream_id:16; }; +struct uasp_common; +struct uasp_lun; +struct uasp_dev; + +enum uasp_state { + UASP_STATE_IDLE = 0, + UASP_STATE_RESET, + UASP_STATE_INTERFACE_CHANGE, + UASP_STATE_CONFIG_CHANGE, + UASP_STATE_DISCONNECT, + UASP_STATE_EXIT, + UASP_STATE_TERMINATED +}; + /** * struct uasp_common - Common data shared by all UASP devices + * @gadget: pointer to the gadget driver * @udev: Programming view of uasp device. - * @common: points to fsg_common in fsg_dev - * @ubufs: buffers to be used by the uasp device. Each element in - * ubufs[i].fsg_buff points to a fsg_buffhd struct from fsg_common data - * structure - * @uluns: luns of the uasp device. Each element in uluns[i].lun points to a - * fsg_lun array element from fsg_common data structure - * - * Extends the struct fsg_common structure. + * @new_udev: Programming view of new uasp device. Used in configuration switch + * @uasp_wait: wait queue + * @filesem: filesem protects: backing files in use + * @lock: lock protects: state, all the req_busy's + * @ubufs: buffers to be used by the uasp device. + * @uluns: luns of the uasp device. + * @nluns: number of luns + * @state: For exception handling + * @running: set to 1 if the UASP interface is active + * @ops: Callback functions. + * @private_data: Gadget's private data. + * @inquiry_string: Vendor (8 chars), product (16 chars), release (4 hexadecimal + * digits) and NULL byte + * @ref: */ struct uasp_common { - struct uasp_dev *udev; - struct fsg_common *common; - struct uasp_buff ubufs[fsg_num_buffers]; + struct usb_gadget *gadget; + struct usb_composite_dev *cdev; + struct msg_common_data *msg_common; + struct uasp_dev *udev, *new_udev; + wait_queue_head_t uasp_wait; + + struct mutex *config_mutex; + + struct rw_semaphore filesem; + spinlock_t lock; + + struct uasp_buff *ubufs; struct uasp_lun *uluns; + + unsigned int nluns; + enum uasp_state state; + unsigned int running:1; + + int thread_wakeup_needed; + struct completion thread_notifier; + struct task_struct *thread_task; + + const struct fsg_operations *ops; + + char inquiry_string[8 + 16 + 4 + 1]; + struct kref ref; }; /** * struct uasp_dev - Programming view of the uasp device - * @fsg_dev: pointer to the fsg_dev this struct extends + * @function: usb function + * @gadget: Copy of cdev->gadget * @ucommon: pointer to the common data of the device + * @bulk_in_enabled: set to 1 when BULK IN ep is enabled + * @bulk_out_enabled: set to 1 when BULK OUT ep is enabled + * @cmd_enabled: set to 1 when COMMAND ep is enabled + * @status_enabled: set to 1 when STATUS ep is enabled + * @bulk_in: BULK IN endpoint + * @bulk_out: BULK OUT endpoint * @status: status endpoint * @command: command endpoint * @cmd_buff: buffer used for receiving commannd IUs @@ -117,19 +176,27 @@ struct uasp_common { * Extends the struct fsg_dev structure. */ struct uasp_dev { - struct fsg_dev fsg_dev; - + struct usb_function function; + struct usb_gadget *gadget; struct uasp_common *ucommon; + + unsigned int bulk_in_enabled:1; + unsigned int bulk_out_enabled:1; + unsigned int cmd_enabled:1; + unsigned int status_enabled:1; + + struct usb_ep *bulk_in; + struct usb_ep *bulk_out; struct usb_ep *status; struct usb_ep *command; + struct fsg_buffhd cmd_buff; -#define HS_UASP_MODE 0 -#define SS_UASP_MODE 1 +#define UASP_MODE_UNSET 0 +#define HS_UASP_MODE 1 +#define SS_UASP_MODE 2 uint8_t op_mode; - - unsigned int cmd_enabled; - unsigned int status_enabled; + unsigned int forced_hs_mode; struct list_head cmd_queue; struct list_head tm_func_queue; @@ -453,4 +520,5 @@ int all_lun_state_non_processing(struct uasp_dev *udev); */ void close_lun(struct uasp_lun *ulun); +int uasp_sleep_thread(struct uasp_common *common); #endif /* _F_UASP_H */ diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index b7d9e7e..5e4c3d2 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -28,9 +28,7 @@ */ -#include <linux/kernel.h> #include <linux/utsname.h> -#include <linux/usb/ch9.h> /*-------------------------------------------------------------------------*/ @@ -95,9 +93,11 @@ static struct fsg_module_parameters mod_data = { FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); static unsigned long msg_registered; +static struct msg_common_data msg_common; + static void msg_cleanup(void); -static int msg_thread_exits(struct fsg_common *common) +static int msg_thread_exits(void *common) { msg_cleanup(); return 0; @@ -105,13 +105,9 @@ static int msg_thread_exits(struct fsg_common *common) static int __init msg_do_config(struct usb_configuration *c) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; static struct fsg_common common; struct fsg_common *retp; - struct fsg_config config; int ret; if (gadget_is_otg(c->cdev->gadget)) { @@ -119,14 +115,11 @@ static int __init msg_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - fsg_config_from_params(&config, &mod_data); - config.ops = &ops; - /* Init fsg_common and start the fsg main thread */ - retp = fsg_common_init(&common, c->cdev, &config, 1); + retp = fsg_common_init(&common, c->cdev, &msg_common.config); if (IS_ERR(retp)) return PTR_ERR(retp); - + common.msg_common = &msg_common; ret = fsg_bind_config(c->cdev, c, &common); fsg_common_put(&common); return ret; @@ -140,25 +133,14 @@ static struct usb_configuration msg_config_driver = { static int __init uasp_do_config(struct usb_configuration *c) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; - - struct fsg_common *fcommon; struct uasp_common *ucommon; - struct fsg_config config; int ret = 0; - fsg_config_from_params(&config, &mod_data); - config.ops = &ops; - fcommon = fsg_common_init(0, c->cdev, &config, 0); - if (IS_ERR(fcommon)) - return PTR_ERR(fcommon); - - ucommon = uasp_common_init(fcommon, c->cdev, &config); + ucommon = uasp_common_init(&msg_common, c->cdev); if (IS_ERR(ucommon)) return PTR_ERR(ucommon); - ret = uasp_add(c->cdev, c, fcommon, ucommon); + msg_common.ucommon = ucommon; + ret = uasp_add(c->cdev, c, ucommon); uasp_common_put(ucommon); return ret; @@ -174,36 +156,38 @@ static struct usb_configuration uasp_config_driver = { /****************************** Gadget Bind ******************************/ -bool use_uasp ; -module_param(use_uasp, bool, S_IRUGO | S_IWUSR); static int __init msg_bind(struct usb_composite_dev *cdev) { int status; - + struct usb_function *fsg_func; + static const struct fsg_operations ops = { + .thread_exits = msg_thread_exits, + }; dev_info(&cdev->gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); - if (use_uasp) { - /* - * TODO: fix the bellow! - * Right now the host always chooses the first configuration. - * Untill this is fixed, if we want the device to opperate in - * UASP mode we switch the configurations numbers - */ - msg_config_driver.bConfigurationValue = 2; - uasp_config_driver.bConfigurationValue = 1; - /* register uasp configuration */ - status = usb_add_config(cdev, &uasp_config_driver, - uasp_do_config); - if (status < 0) - return status; - } else { - /* register our second configuration */ - status = usb_add_config(cdev, &msg_config_driver, - msg_do_config); - if (status < 0) - return status; - } + fsg_config_from_params(&msg_common.config, &mod_data); + msg_common.config.ops = &ops; + msg_common.config.uasp_ops = &ops; + mutex_init(&msg_common.config.config_mutex); + + /* register MS-BOT configuration */ + status = usb_add_config(cdev, &msg_config_driver, + msg_do_config); + if (status < 0) + return status; + + fsg_func = list_first_entry(&msg_config_driver.functions, + struct usb_function, + list); + msg_common.fcommon = (fsg_from_func(fsg_func))->common; + + /* Register MS-UAS configuration */ + status = usb_add_config(cdev, &uasp_config_driver, uasp_do_config); + if (status < 0) + return status; + + set_bit(0, &msg_registered); return 0; } @@ -233,5 +217,9 @@ static void msg_cleanup(void) { if (test_and_clear_bit(0, &msg_registered)) usb_composite_unregister(&msg_driver); + memset(&msg_common.config, 0, sizeof(struct fsg_config)); + + msg_common.fcommon = NULL; + msg_common.ucommon = NULL; } module_exit(msg_cleanup); diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 4937ad6..6e84b27 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -46,7 +46,7 @@ /* * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers * sets the number of pipeline buffers (length of the fsg_buffhd array). - * The valid range of num_buffers is: num >= 2 && num <= 4. + * The valid range of num_buffers is: num >= 256 && num <= 1024. */ @@ -252,6 +252,70 @@ struct fsg_lun { #define fsg_lun_is_open(curlun) ((curlun)->filp != NULL) +/* FSF callback functions */ +struct fsg_operations { + /* + * Callback function to call when thread exits. If no + * callback is set or it returns value lower then zero MSF + * will force eject all LUNs it operates on (including those + * marked as non-removable or with prevent_medium_removal flag + * set). + */ + int (*thread_exits)(void *common); + + /* + * Called prior to ejection. Negative return means error, + * zero means to continue with ejection, positive means not to + * eject. + */ + int (*pre_eject)(void *common, + struct fsg_lun *lun, int num); + /* + * Called after ejection. Negative return means error, zero + * or positive is just a success. + */ + int (*post_eject)(void *common, + struct fsg_lun *lun, int num); +}; + +/* Maximal number of LUNs supported in mass storage function */ +#define FSG_MAX_LUNS 8 + +struct fsg_config { + unsigned nluns; + struct fsg_lun_config { + const char *filename; + char ro; + char removable; + char cdrom; + char nofua; + } luns[FSG_MAX_LUNS]; + + const char *lun_name_format; + const char *thread_name; + + /* Callback functions. */ + const struct fsg_operations *ops; + /* UAS Callback functions. */ + const struct fsg_operations *uasp_ops; + /* Gadget's private data. */ + void *private_data; + struct mutex config_mutex; + + const char *vendor_name; /* 8 characters or less */ + const char *product_name; /* 16 characters or less */ + u16 release; + + char can_stall; +}; + +struct msg_common_data { + struct fsg_config config; + struct fsg_common *fcommon; + struct uasp_common *ucommon; +}; + + static struct fsg_lun *fsg_lun_from_dev(struct device *dev) { return container_of(dev, struct fsg_lun, dev); diff --git a/drivers/usb/gadget/uasp_cmdiu.c b/drivers/usb/gadget/uasp_cmdiu.c index 8836945..61902e4 100644 --- a/drivers/usb/gadget/uasp_cmdiu.c +++ b/drivers/usb/gadget/uasp_cmdiu.c @@ -27,14 +27,14 @@ * This function tries to find a free buffer for COMMAND IU or * TM FUNCTION IU processing. */ -struct fsg_buffhd *get_buffhd(struct fsg_buffhd *bh) +struct fsg_buffhd *get_buffhd(struct uasp_buff *bh) { int i; for (i = 0; i < fsg_num_buffers; i++) { - if (bh[i].state == BUF_STATE_EMPTY) { - bh[i].state = BUF_STATE_BUSY; - return &bh[i]; + if (bh[i].fsg_buff->state == BUF_STATE_EMPTY) { + bh[i].fsg_buff->state = BUF_STATE_BUSY; + return bh[i].fsg_buff; } } @@ -56,12 +56,12 @@ static __u32 check_cmdiu(struct uasp_dev *udev, { __u32 ua_data = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (!curlun || !curlun->lun) { if (cmdiu->cdb[0] != INQUIRY && cmdiu->cdb[0] != REQUEST_SENSE) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - Logical unit is not supported\n", __func__); return SS_LOGICAL_UNIT_NOT_SUPPORTED; @@ -70,18 +70,24 @@ static __u32 check_cmdiu(struct uasp_dev *udev, if (curlun->lun->unit_attention_data && cmdiu->cdb[0] != INQUIRY && cmdiu->cdb[0] != REQUEST_SENSE) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - There is an unit attention condition\n", __func__); ua_data = curlun->lun->unit_attention_data; curlun->lun->unit_attention_data = SS_NO_SENSE; return ua_data; } + /* HACK!!! REMOVE!!! */ + if (curlun->lun->unit_attention_data == SS_RESET_OCCURRED && + cmdiu->cdb[0] == INQUIRY) { + curlun->lun->unit_attention_data = SS_NO_SENSE; + DBG(udev->ucommon, "check_cmdiu() - " + "HACK!!! RESETTING unit attention condition\n"); + } } if (curlun && !(curlun->lun->filp) && needs_medium) { - DBG(udev->ucommon->common, - "%s() - Medium is not present\n", __func__); + DBG(udev->ucommon, "%s() - Medium is not present\n", __func__); return SS_MEDIUM_NOT_PRESENT; } @@ -102,7 +108,7 @@ void fill_sense_iu(struct uasp_dev *udev, __u8 status, __u32 sense_data) { - DBG(udev->ucommon->common, "%s() - Status = %02x\n", __func__, status); + DBG(udev->ucommon, "%s() - Status = %02x\n", __func__, status); siu->iu_id = IU_ID_SENSE; siu->reserved1 = 0; @@ -147,14 +153,14 @@ static int do_uasp_inquiry(struct uasp_dev *udev, struct cmd_iu *cmdiu) { struct fsg_buffhd *bh = cmdiu->bh; - struct fsg_common *common = udev->ucommon->common; + struct uasp_common *ucommon = udev->ucommon; struct usb_request *req = bh->inreq; __u8 *buf = (__u8 *)bh->buf; __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; int rc = 0; - DBG(common, "%s() - Enter\n", __func__); + DBG(ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { /* Check is cmdiu is filled correctly */ @@ -162,7 +168,7 @@ static int do_uasp_inquiry(struct uasp_dev *udev, /* If error sent status with sense data */ if (sense) { - ERROR(common, "%s() - Error condition\n", __func__); + ERROR(ucommon, "%s() - Error condition\n", __func__); status = STATUS_CHECK_CONDITION; cmdiu->state = COMMAND_STATE_STATUS; } else if (udev->op_mode == HS_UASP_MODE) @@ -213,8 +219,8 @@ static int do_uasp_inquiry(struct uasp_dev *udev, buf[5] = 0; /* No special options */ buf[6] = 0; buf[7] = 0; - memcpy(buf + 8, common->inquiry_string, - sizeof(common->inquiry_string)); + memcpy(buf + 8, ucommon->inquiry_string, + sizeof(ucommon->inquiry_string)); } fill_usb_request(req, bh->buf, @@ -224,7 +230,7 @@ static int do_uasp_inquiry(struct uasp_dev *udev, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; @@ -286,7 +292,7 @@ static int do_uasp_request_sense(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { /* Check is cmdiu is filled correctly */ @@ -377,7 +383,7 @@ static int do_uasp_request_sense(struct uasp_dev *udev, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; @@ -401,7 +407,7 @@ static int do_uasp_request_sense(struct uasp_dev *udev, break; } - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return rc; } @@ -424,7 +430,7 @@ static int do_uasp_test_unit_ready(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Check is cmdiu is filled correctly */ sense = check_cmdiu(udev, curlun, cmdiu, 0); @@ -472,7 +478,7 @@ static int do_uasp_mode_sense(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { sense = check_cmdiu(udev, curlun, cmdiu, 0); @@ -592,7 +598,7 @@ static int do_uasp_mode_sense(struct uasp_dev *udev, fill_usb_request(req, buf0, len, 0, cmdiu, 0, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; @@ -637,7 +643,7 @@ static int do_uasp_prevent_allow(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Check is cmdiu is filled correctly */ sense = check_cmdiu(udev, curlun, cmdiu, 0); @@ -699,11 +705,11 @@ static int do_uasp_read(struct uasp_dev *udev, __u8 status = STATUS_GOOD; int rc = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { if (!curlun) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Error condition - curlun = NULL\n", __func__); sense = SS_LOGICAL_UNIT_NOT_SUPPORTED; @@ -759,7 +765,7 @@ static int do_uasp_read(struct uasp_dev *udev, cmdiu->state = COMMAND_STATE_DATA; cmdiu->req_sts = CMD_REQ_NOT_SUBMITTED; - DBG(udev->ucommon->common, "%s() lba = %d, file_offset = %d," + DBG(udev->ucommon, "%s() lba = %d, file_offset = %d," " xfer_len = %d\n", __func__, lba, cmdiu->file_offset, cmdiu->xfer_len); } @@ -867,19 +873,19 @@ send_more_data: /* fill_usb_request(req, bh->buf, nread, 0, cmdiu, 0, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; } else if (cmdiu->req_sts == CMD_REQ_IN_PROGRESS) { /* Completion of sent data is not received yet */ - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - completion for bh is not received", __func__); break; } else { /* Completion of the sent data is done */ - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - COMMAND_STATE_DATA for bh\n", __func__); if (cmdiu->xfer_len == 0) goto send_status; @@ -926,7 +932,7 @@ static int do_uasp_read_capacity(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { /* Check is cmdiu is filled correctly */ @@ -987,7 +993,7 @@ static int do_uasp_read_capacity(struct uasp_dev *udev, cmdiu, 0, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; @@ -1034,7 +1040,7 @@ static int do_uasp_read_format_capacities(struct uasp_dev *udev, __u8 status = STATUS_GOOD; int rc = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (cmdiu->state == COMMAND_STATE_IDLE) { /* Check is cmdiu is filled correctly */ @@ -1096,7 +1102,7 @@ static int do_uasp_read_format_capacities(struct uasp_dev *udev, cmdiu, 0, be16_to_cpup(&cmdiu->tag), uasp_bulk_in_complete, udev->op_mode); - cmdiu->ep = udev->fsg_dev.bulk_in; + cmdiu->ep = udev->bulk_in; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 1; break; @@ -1118,7 +1124,7 @@ static int do_uasp_read_format_capacities(struct uasp_dev *udev, break; } - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return rc; } @@ -1143,7 +1149,7 @@ static int do_uasp_start_stop(struct uasp_dev *udev, __u8 status = STATUS_GOOD; int start, loej; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); start = cmdiu->cdb[4] & 0x01; loej = cmdiu->cdb[4] & 0x02; @@ -1190,7 +1196,7 @@ static int do_uasp_start_stop(struct uasp_dev *udev, } else { /* Are we allowed to unload the media? */ if (curlun->lun->prevent_medium_removal) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s(): unload attempt prevented\n", __func__); sense = SS_MEDIUM_REMOVAL_PREVENTED; @@ -1199,10 +1205,10 @@ static int do_uasp_start_stop(struct uasp_dev *udev, } /* Simulate an unload/eject */ - if (udev->ucommon->common->ops && - udev->ucommon->common->ops->pre_eject) { - int r = udev->ucommon->common->ops->pre_eject( - udev->ucommon->common, curlun->lun, + if (udev->ucommon->ops && + udev->ucommon->ops->pre_eject) { + int r = udev->ucommon->ops->pre_eject( + udev->ucommon, curlun->lun, curlun - udev->ucommon->uluns); if (unlikely(r < 0)) status = STATUS_CHECK_CONDITION; @@ -1210,18 +1216,17 @@ static int do_uasp_start_stop(struct uasp_dev *udev, goto do_uasp_start_stop_done; } - up_read(&(udev->ucommon->common->filesem)); - down_write(&(udev->ucommon->common->filesem)); + up_read(&(udev->ucommon->filesem)); + down_write(&(udev->ucommon->filesem)); close_lun(curlun); - up_write(&(udev->ucommon->common->filesem)); - down_read(&(udev->ucommon->common->filesem)); - - if (udev->ucommon->common->ops && - udev->ucommon->common->ops->post_eject) { - if (udev->ucommon->common->ops-> - post_eject(udev->ucommon->common, - curlun->lun, - curlun - udev->ucommon->uluns) + up_write(&(udev->ucommon->filesem)); + down_read(&(udev->ucommon->filesem)); + + if (udev->ucommon->ops && + udev->ucommon->ops->post_eject) { + if (udev->ucommon->ops-> + post_eject(udev->ucommon, curlun->lun, + curlun - udev->ucommon->uluns) < 0) status = STATUS_CHECK_CONDITION; } @@ -1237,7 +1242,7 @@ do_uasp_start_stop_done: udev->op_mode); cmdiu->ep = udev->status; - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return 1; } @@ -1267,7 +1272,7 @@ static int do_uasp_verify(struct uasp_dev *udev, __u32 sense = SS_NO_SENSE; __u8 status = STATUS_GOOD; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); file_offset = (get_unaligned_be32(&cmdiu->cdb[2]) << 9); ver_len = (get_unaligned_be32(&cmdiu->cdb[7]) << 9); @@ -1354,7 +1359,7 @@ static int do_uasp_verify(struct uasp_dev *udev, be16_to_cpup(&cmdiu->tag), status_complete, udev->op_mode); cmdiu->ep = udev->status; - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return 1; } @@ -1386,10 +1391,10 @@ static int do_uasp_write(struct uasp_dev *udev, __u8 status = STATUS_GOOD; int rc = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); if (!curlun) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() - Error condition - curlun = NULL\n", __func__); sense = SS_LOGICAL_UNIT_NOT_SUPPORTED; @@ -1474,7 +1479,7 @@ static int do_uasp_write(struct uasp_dev *udev, else cmdiu->state = COMMAND_STATE_DATA; cmdiu->req_sts = CMD_REQ_NOT_SUBMITTED; - DBG(udev->ucommon->common, "%s() lba = %d, file_offset = %d," + DBG(udev->ucommon, "%s() lba = %d, file_offset = %d," " xfer_len = %d\n", __func__, lba, cmdiu->file_offset, cmdiu->xfer_len); } @@ -1549,11 +1554,11 @@ get_more_data: if (cmdiu->req_sts == CMD_REQ_NOT_SUBMITTED) { fill_usb_request(req, bh->buf, amount, 0, cmdiu, 0, be16_to_cpup(&cmdiu->tag), uasp_bulk_out_complete, udev->op_mode); - DBG(udev->ucommon->common, "%s() fill_usb_request for" + DBG(udev->ucommon, "%s() fill_usb_request for" " out endpoint, amout = %d", __func__, amount); - cmdiu->ep = udev->fsg_dev.bulk_out; + cmdiu->ep = udev->bulk_out; cmdiu->req_sts = CMD_REQ_IN_PROGRESS; rc = 2; break; @@ -1577,7 +1582,7 @@ get_more_data: if (cmdiu->req_sts == CMD_REQ_NOT_SUBMITTED) { * request for this command, we should abort * all submitted requests for this command */ - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - Host aborted the command\n", __func__); goto send_status; @@ -1586,7 +1591,7 @@ get_more_data: if (cmdiu->req_sts == CMD_REQ_NOT_SUBMITTED) { amount = req->actual; if (curlun->lun->file_length - cmdiu->file_offset < amount) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s(): write %u @ %llu beyond end %llu\n", __func__, amount, (unsigned long long)cmdiu->file_offset, @@ -1601,18 +1606,18 @@ get_more_data: if (cmdiu->req_sts == CMD_REQ_NOT_SUBMITTED) { nwritten = vfs_write(curlun->lun->filp, (char __user *) bh->buf, amount, &file_offset_tmp); - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s(): file write %u @ %llu -> %d\n", __func__, amount, (unsigned long long)cmdiu->file_offset, (int)nwritten); if (nwritten < 0) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s(): error in file write: %d\n", __func__, (int)nwritten); nwritten = 0; } else if (nwritten < amount) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s(): partial file write: %d/%u\n", __func__, (int)nwritten, amount); nwritten -= (nwritten & 511); @@ -1633,7 +1638,7 @@ get_more_data: if (cmdiu->req_sts == CMD_REQ_NOT_SUBMITTED) { } if (cmdiu->xfer_len == 0) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - cmdiu->xferlen = 0, " "send status\n", __func__); goto send_status; @@ -1657,7 +1662,7 @@ send_status: break; } - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return rc; } @@ -1682,7 +1687,7 @@ static int do_uasp_synchronize_cache(struct uasp_dev *udev, uint8_t status = STATUS_GOOD; int rc; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Check is cmdiu is filled correctly */ sense = check_cmdiu(udev, curlun, cmdiu, 0); @@ -1707,7 +1712,7 @@ static int do_uasp_synchronize_cache(struct uasp_dev *udev, udev->op_mode); cmdiu->ep = udev->status; - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); return 1; } @@ -1727,11 +1732,11 @@ static void process_cmdiu(struct uasp_dev *udev, struct usb_request *req; int rc = 0; - DBG(udev->ucommon->common, "%s() Enter. (cmdiu->cdb[0]=%04x)\n", + DBG(udev->ucommon, "%s() Enter. (cmdiu->cdb[0]=%04x)\n", __func__, cmdiu->cdb[0]); /* We're using the backing file */ - down_read(&udev->ucommon->common->filesem); + down_read(&udev->ucommon->filesem); switch (cmdiu->cdb[0]) { case INQUIRY: rc = do_uasp_inquiry(udev, curlun, cmdiu); @@ -1781,7 +1786,7 @@ static void process_cmdiu(struct uasp_dev *udev, case RESERVE: case SEND_DIAGNOSTIC: default: - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s(): Unsupported command = %x\n", __func__, cmdiu->cdb[0]); cmdiu->state = COMMAND_STATE_STATUS; @@ -1798,7 +1803,7 @@ static void process_cmdiu(struct uasp_dev *udev, break; } - up_read(&udev->ucommon->common->filesem); + up_read(&udev->ucommon->filesem); if (rc) { if (rc == 1) { req = cmdiu->bh->inreq; @@ -1808,11 +1813,11 @@ static void process_cmdiu(struct uasp_dev *udev, cmdiu->bh->outreq_busy = 1; } if (usb_ep_queue(cmdiu->ep, req, 0)) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s()usb_ep_queue failed\n", __func__); cmdiu->state = COMMAND_STATE_FAILED; } else { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - process_cmdiu: queued req to ep\n", __func__); if (curlun) { @@ -1821,10 +1826,10 @@ static void process_cmdiu(struct uasp_dev *udev, spin_unlock_irqrestore(&(curlun->lock), flags); } else { spin_lock_irqsave( - &(udev->ucommon->common->lock), flags); + &(udev->ucommon->lock), flags); udev->active_requests++; spin_unlock_irqrestore( - &(udev->ucommon->common->lock), flags); + &(udev->ucommon->lock), flags); } } } @@ -1843,7 +1848,7 @@ void do_cmdiu(struct uasp_dev *udev, struct uasp_lun *curlun) struct cmd_iu *cmdiu, *tmp; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Select the cmd_queue from which cmdius should be processed */ if (curlun) @@ -1852,18 +1857,18 @@ void do_cmdiu(struct uasp_dev *udev, struct uasp_lun *curlun) link = &udev->cmd_queue; list_for_each_entry_safe(cmdiu, tmp, link, node) { - DBG(udev->ucommon->common, "%s() - Rolling over cmdiu queue\n", + DBG(udev->ucommon, "%s() - Rolling over cmdiu queue\n", __func__); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); if (cmdiu->state == COMMAND_STATE_IDLE) { /* Try to get buffers for cmdiu processing */ - cmdiu->bh = get_buffhd(udev->ucommon->common->buffhds); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), + cmdiu->bh = get_buffhd(udev->ucommon->ubufs); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); if (!cmdiu->bh) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() -Didn't manage to get buffers for " "cmdiu!\n", __func__); continue; @@ -1872,15 +1877,14 @@ void do_cmdiu(struct uasp_dev *udev, struct uasp_lun *curlun) cmdiu->state == COMMAND_STATE_RR_WR) { if (cmdiu->req_sts == CMD_REQ_COMPLETED) spin_unlock_irqrestore( - &(udev->ucommon->common->lock), flags); + &(udev->ucommon->lock), flags); else { spin_unlock_irqrestore( - &(udev->ucommon->common->lock), flags); + &(udev->ucommon->lock), flags); continue; } } else { - spin_unlock_irqrestore(&(udev->ucommon->common->lock), - flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); continue; } diff --git a/drivers/usb/gadget/uasp_tmiu.c b/drivers/usb/gadget/uasp_tmiu.c index 5f70424..8f8fd86 100644 --- a/drivers/usb/gadget/uasp_tmiu.c +++ b/drivers/usb/gadget/uasp_tmiu.c @@ -32,7 +32,7 @@ void fill_response_iu(struct uasp_dev *udev, uint32_t resp_info, uint8_t status) { - DBG(udev->ucommon->common, "%s() - Enter. Status = %02x\n", __func__, + DBG(udev->ucommon, "%s() - Enter. Status = %02x\n", __func__, status); riu->iu_id = IU_ID_RESPONSE; riu->reserved = 0; @@ -61,7 +61,7 @@ static void reset_lun(struct uasp_dev *udev, uint8_t status; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { @@ -108,7 +108,7 @@ static void abort_task(struct uasp_dev *udev, unsigned long flags; uint8_t status; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { status = RESPONSE_INCORRECT_LUN; @@ -121,7 +121,7 @@ static void abort_task(struct uasp_dev *udev, goto found; /* Command with specified ipt_tag not found */ - DBG(udev->ucommon->common, "%s(): cmdiu with tag %04x wasn't found\n", + DBG(udev->ucommon, "%s(): cmdiu with tag %04x wasn't found\n", __func__, tmiu->task_tag); cmdiu = 0; @@ -177,7 +177,7 @@ static void abort_task_set(struct uasp_dev *udev, uint8_t status; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { @@ -215,7 +215,7 @@ static void reset_nexus(struct uasp_dev *udev, uint8_t status; int rc = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; @@ -226,26 +226,27 @@ static void reset_nexus(struct uasp_dev *udev, * Sleep if luns are in processing */ while (!all_lun_state_non_processing(udev)) { - DBG(udev->ucommon->common, + DBG(udev->ucommon, "%s() - Luns are in process. Going to sleep\n", __func__); - rc = sleep_thread(udev->ucommon->common); + rc = uasp_sleep_thread(udev->ucommon); if (rc) { - ERROR(udev->ucommon->common, - "%s() - sleep_thread failed! (%d)", __func__, rc); + ERROR(udev->ucommon, + "%s() - uasp_sleep_thread failed! (%d)", + __func__, rc); status = RESPONSE_TM_FUNCTION_FAILED; goto reset_nexus_fill_response; } - DBG(udev->ucommon->common, "%s() - Wakes up\n", __func__); + DBG(udev->ucommon, "%s() - Wakes up\n", __func__); rc = 0; } /* Abort general commands and tmius */ abort_commands(udev, &udev->cmd_queue, &udev->tm_func_queue, - &(udev->ucommon->common->lock)); + &(udev->ucommon->lock)); - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); udev->pending_requests = 0; - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); status = RESPONSE_TM_FUNCTION_COMPLETE; reset_nexus_fill_response: @@ -255,7 +256,7 @@ reset_nexus_fill_response: 0, (void *)tmiu, 0, be16_to_cpup(&tmiu->tag), status_complete, udev->op_mode); tmiu->ep = udev->status; - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); } /** @@ -277,7 +278,7 @@ static void query_unit_attention(struct uasp_dev *udev, uint8_t status; uint32_t resp_info = 0; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { status = RESPONSE_INCORRECT_LUN; @@ -324,7 +325,7 @@ static void query_task(struct uasp_dev *udev, unsigned long flags; uint8_t status = RESPONSE_TM_FUNCTION_COMPLETE; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { status = RESPONSE_INCORRECT_LUN; @@ -371,7 +372,7 @@ static void query_task_set(struct uasp_dev *udev, unsigned long flags; uint8_t status; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); riu = (struct response_iu *)tmiu->bh->buf; if (!curlun) { status = RESPONSE_INCORRECT_LUN; @@ -400,7 +401,7 @@ q_task_set_fill_response: 0, (void *)tmiu, 0, be16_to_cpup(&tmiu->tag), status_complete, udev->op_mode); tmiu->ep = udev->status; - DBG(udev->ucommon->common, "%s() - Exit\n", __func__); + DBG(udev->ucommon, "%s() - Exit\n", __func__); } /** @@ -448,7 +449,7 @@ static void process_tmiu(struct uasp_dev *udev, break; default: - ERROR(udev->ucommon->common, "%s(): Unsupported tmiu = %x\n", + ERROR(udev->ucommon, "%s(): Unsupported tmiu = %x\n", __func__, tmiu->tm_function); riu = (struct response_iu *)tmiu->bh->inreq->buf; fill_response_iu(udev, riu, tmiu->tag, 0, @@ -464,8 +465,7 @@ static void process_tmiu(struct uasp_dev *udev, tmiu->state = COMMAND_STATE_STATUS; if (usb_ep_queue(tmiu->ep, tmiu->bh->inreq, 0)) { - ERROR(udev->ucommon->common, - "%s()usb_ep_queue failed\n", __func__); + ERROR(udev->ucommon, "%s()usb_ep_queue failed\n", __func__); tmiu->state = COMMAND_STATE_FAILED; } else { tmiu->bh->inreq_busy = 1; @@ -474,10 +474,10 @@ static void process_tmiu(struct uasp_dev *udev, curlun->active_requests++; spin_unlock_irqrestore(&(curlun->lock), flags); } else { - spin_lock_irqsave(&(udev->ucommon->common->lock), + spin_lock_irqsave(&(udev->ucommon->lock), flags); udev->active_requests++; - spin_unlock_irqrestore(&(udev->ucommon->common->lock), + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); } } @@ -497,7 +497,7 @@ void do_tmiu(struct uasp_dev *udev, struct uasp_lun *curlun) struct tm_iu *tmiu, *tmp; unsigned long flags; - DBG(udev->ucommon->common, "%s() - Enter\n", __func__); + DBG(udev->ucommon, "%s() - Enter\n", __func__); /* Select the tm_func_queue from which tmius should be processed */ if (curlun) @@ -505,19 +505,19 @@ void do_tmiu(struct uasp_dev *udev, struct uasp_lun *curlun) else link = &udev->tm_func_queue; - DBG(udev->ucommon->common, "%s() - Rolling over tmiu queue\n", + DBG(udev->ucommon, "%s() - Rolling over tmiu queue\n", __func__); list_for_each_entry_safe(tmiu, tmp, link, node) { if (tmiu->state != COMMAND_STATE_IDLE) continue; /* Try to get buffer for tmiu provessing */ - spin_lock_irqsave(&(udev->ucommon->common->lock), flags); - tmiu->bh = get_buffhd(udev->ucommon->common->buffhds); - spin_unlock_irqrestore(&(udev->ucommon->common->lock), flags); + spin_lock_irqsave(&(udev->ucommon->lock), flags); + tmiu->bh = get_buffhd(udev->ucommon->ubufs); + spin_unlock_irqrestore(&(udev->ucommon->lock), flags); if (!tmiu->bh) { - ERROR(udev->ucommon->common, + ERROR(udev->ucommon, "%s() -Didnt manage to get buffers for tmiu!\n", __func__); continue; -- 1.7.6 -- Sent by a Consultant for Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html