[PATCH V2 6/9] scsi: ufs: fix interrupt status clears
There is no need to check the version to clear the interrupt status. And the order is changed prior to actual handling. Signed-off-by: Seungwon Jeon tgih@samsung.com Tested-by: Maya Erez me...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c342a38..f4293d1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1478,11 +1478,8 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); if (intr_status) { + ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); ufshcd_sl_intr(hba, intr_status); - - /* If UFSHCI 1.0 then clear interrupt status register */ - if (hba-ufs_version == UFSHCI_VERSION_10) - ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); retval = IRQ_HANDLED; } spin_unlock(hba-host-host_lock); -- 1.7.6 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 7/9] scsi: ufs: rework link start-up process
Link start-up requires long time with multiphase handshakes between UFS host and device. This affects driver's probe time. This patch let link start-up run asynchronously. Link start-up will be executed at the end of prove separately. Along with this change, the following is worked. Defined completion time of uic command to avoid a permanent wait. Added mutex to guarantee of uic command at a time. Adapted some sequence of controller initialization after link statup according to HCI standard. Signed-off-by: Seungwon Jeon tgih@samsung.com Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Tested-by: Maya Erez me...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index f4293d1..333812f 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -33,11 +33,15 @@ * this program. */ +#include linux/async.h + #include ufshcd.h #define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\ UTP_TASK_REQ_COMPL |\ UFSHCD_ERROR_MASK) +/* UIC command timeout, unit: ms */ +#define UIC_CMD_TIMEOUT500 enum { UFSHCD_MAX_CHANNEL = 0, @@ -401,24 +405,122 @@ static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) } /** - * ufshcd_send_uic_command - Send UIC commands to unipro layers + * ufshcd_ready_for_uic_cmd - Check if controller is ready + *to accept UIC commands * @hba: per adapter instance - * @uic_command: UIC command + * Return true on success, else false + */ +static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) +{ + if (ufshcd_readl(hba, REG_CONTROLLER_STATUS) UIC_COMMAND_READY) + return true; + else + return false; +} + +/** + * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Mutex must be held. */ static inline void -ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd) +ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) { + WARN_ON(hba-active_uic_cmd); + + hba-active_uic_cmd = uic_cmd; + /* Write Args */ - ufshcd_writel(hba, uic_cmnd-argument1, REG_UIC_COMMAND_ARG_1); - ufshcd_writel(hba, uic_cmnd-argument2, REG_UIC_COMMAND_ARG_2); - ufshcd_writel(hba, uic_cmnd-argument3, REG_UIC_COMMAND_ARG_3); + ufshcd_writel(hba, uic_cmd-argument1, REG_UIC_COMMAND_ARG_1); + ufshcd_writel(hba, uic_cmd-argument2, REG_UIC_COMMAND_ARG_2); + ufshcd_writel(hba, uic_cmd-argument3, REG_UIC_COMMAND_ARG_3); /* Write UIC Cmd */ - ufshcd_writel(hba, uic_cmnd-command COMMAND_OPCODE_MASK, + ufshcd_writel(hba, uic_cmd-command COMMAND_OPCODE_MASK, REG_UIC_COMMAND); } /** + * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command + * @hba: per adapter instance + * @uic_command: UIC command + * + * Must be called with mutex held. + * Returns 0 only if success. + */ +static int +ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + unsigned long flags; + + if (wait_for_completion_timeout(uic_cmd-done, + msecs_to_jiffies(UIC_CMD_TIMEOUT))) + ret = uic_cmd-argument2 MASK_UIC_COMMAND_RESULT; + else + ret = -ETIMEDOUT; + + spin_lock_irqsave(hba-host-host_lock, flags); + hba-active_uic_cmd = NULL; + spin_unlock_irqrestore(hba-host-host_lock, flags); + + return ret; +} + +/** + * __ufshcd_send_uic_cmd - Send UIC commands and retrieve the result + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called + * with mutex held. + * Returns 0 only if success. + */ +static int +__ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + unsigned long flags; + + if (!ufshcd_ready_for_uic_cmd(hba)) { + dev_err(hba-dev, + Controller not ready to accept UIC commands\n); + return -EIO; + } + + init_completion(uic_cmd-done); + + spin_lock_irqsave(hba-host-host_lock, flags); + ufshcd_dispatch_uic_cmd(hba, uic_cmd); + spin_unlock_irqrestore(hba-host-host_lock, flags); + + ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); + + return ret; +} + +/** + * ufshcd_send_uic_cmd - Send UIC commands and retrieve the result + * @hba: per adapter instance + * @uic_cmd: UIC command + * + * Returns 0 only if success. + */ +static int +ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) +{ + int ret; + + mutex_lock(hba-uic_cmd_mutex); + ret = __ufshcd_send_uic_cmd(hba, uic_cmd); + mutex_unlock(hba-uic_cmd_mutex); + + return ret; +} + +/** * ufshcd_map_sg - Map
[PATCH V2 9/9] scsi: ufs: Set fDeviceInit flag to initiate device initialization
Allow UFS device to complete its initialization and accept SCSI commands by setting fDeviceInit flag. The device may take time for this operation and hence the host should poll until fDeviceInit flag is toggled to zero. This step is mandated by UFS device specification for device initialization completion. Signed-off-by: Dolev Raviv dra...@codeaurora.org Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 086ff03..742363d 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -107,8 +107,13 @@ enum { UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81, }; +/* Flag idn for Query Requests*/ +enum flag_idn { + QUERY_FLAG_IDN_FDEVICEINIT = 0x01, +}; + /* UTP QUERY Transaction Specific Fields OpCode */ -enum { +enum query_opcode { UPIU_QUERY_OPCODE_NOP = 0x0, UPIU_QUERY_OPCODE_READ_DESC = 0x1, UPIU_QUERY_OPCODE_WRITE_DESC= 0x2, @@ -208,6 +213,9 @@ struct utp_upiu_query { u32 reserved[2]; }; +/* Expose the flag value from utp_upiu_query.value */ +#define MASK_QUERY_UPIU_FLAG_LOC 0xFF + /** * struct utp_upiu_req - general upiu request structure * @header:UPIU header structure DW-0 to DW-2 diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2db550b..e9dba33 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -50,6 +50,15 @@ /* Reserved tag for internal commands */ #define INTERNAL_CMD_TAG 0 +/* Query request standart retries */ +#define QUERY_REQ_RETRIES 10 +/* Query request standart timeout in seconds */ +#define QUERY_REQ_TIMEOUT 5 +/* Send Query Requst with default parameters */ +#define send_query_request(ARG1, ARG2, ARG3, ARG4) \ + ufshcd_query_request(ARG1, ARG2, ARG3, ARG4,\ + QUERY_REQ_TIMEOUT, QUERY_REQ_RETRIES) + enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, @@ -862,6 +871,164 @@ out: } /** + * ufshcd_query_request() - Entry point for issuing query request to a + * ufs device. + * @hba: ufs driver context + * @query: params for query request + * @descriptor: buffer for sending/receiving descriptor + * @response: pointer to a buffer that will contain the response code and + * response upiu + * @timeout: time limit for the command in seconds + * @retries: number of times to try executing the command + * + * The query request is submitted to the same request queue as the rest of + * the scsi commands passed to the UFS controller. In order to use this + * queue, we need to receive a tag, same as all other commands. The tags + * are issued from the block layer. To simulate a request from the block + * layer, we use the same interface as the SCSI layer does when it issues + * commands not generated by users. To distinguish a query request from + * the SCSI commands, we use a vendor specific unused SCSI command + * op-code. This op-code is not part of the SCSI command subset used in + * UFS. In such way it is easy to check the command in the driver and + * handle it appropriately. + * + * All necessary fields for issuing a query and receiving its response are + * stored in the UFS hba struct. We can use this method since we know + * there is only one active query request at all times. + * + * The request that will pass to the device is stored in query argument + * passed to this function, while the response argument (which is output + * field) will hold the query response from the device along with the + * response code. + */ +int ufshcd_query_request(struct ufs_hba *hba, + struct ufs_query_req *query, + u8 *descriptor, + struct ufs_query_res *response, + int timeout, + int retries) +{ + struct scsi_device *sdev; + u8 cmd[UFS_QUERY_CMD_SIZE] = {0}; + int result; + bool sdev_lookup = true; + + BUG_ON(!hba); + if (!query || !response) { + dev_err(hba-dev, + %s: NULL pointer hba = %p, query = %p response = %p\n, + __func__, hba, query, response); + return -EINVAL; + } + + /* +* A SCSI command structure is composed from opcode at the +* begining and 0 at the end. +*/ + cmd[0] = UFS_QUERY_RESERVED_SCSI_CMD; + + /* extracting the SCSI Device */ + sdev = scsi_device_lookup(hba-host, 0, 0, 0); + if (!sdev) { + /** +* There are some Query Requests that are sent during device +* initialization, this happens before the scsi device was +* initialized. If there is no scsi device, we generate a +* temporary device to allow the Query Request flow. +*/ + sdev_lookup = false; + sdev =
[PATCH V2 8/9] scsi: ufs: Add support for sending NOP OUT UPIU
As part of device initialization sequence, sending NOP OUT UPIU and waiting for NOP IN UPIU response is mandatory. This confirms that the device UFS Transport (UTP) layer is functional and the host can configure the device with further commands. Add support for sending NOP OUT UPIU to check the device connection path and test whether the UTP layer on the device side is functional during initialization. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com Tested-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 333812f..2db550b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -43,6 +43,13 @@ /* UIC command timeout, unit: ms */ #define UIC_CMD_TIMEOUT500 +/* NOP OUT retries waiting for NOP IN response */ +#define NOP_OUT_RETRIES10 +/* Timeout after 30 msecs if NOP OUT hangs without response */ +#define NOP_OUT_TIMEOUT30 /* msecs */ +/* Reserved tag for internal commands */ +#define INTERNAL_CMD_TAG 0 + enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, @@ -71,6 +78,39 @@ enum { INT_AGGR_CONFIG, }; +/* + * ufshcd_wait_for_register - wait for register value to change + * @hba - per-adapter interface + * @reg - mmio register offset + * @mask - mask to apply to read register value + * @val - wait condition + * @interval_us - polling interval in microsecs + * @timeout_ms - timeout in millisecs + * + * Returns final register value after iteration + */ +static u32 ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, + u32 val, unsigned long interval_us, unsigned long timeout_ms) +{ + u32 tmp; + ktime_t start; + unsigned long diff; + + tmp = ufshcd_readl(hba, reg); + + start = ktime_get(); + while ((tmp mask) == val) { + /* wakeup within 50us of expiry */ + usleep_range(interval_us, interval_us + 50); + tmp = ufshcd_readl(hba, reg); + diff = ktime_to_ms(ktime_sub(ktime_get(), start)); + if (diff timeout_ms) + break; + } + + return tmp; +} + /** * ufshcd_get_intr_mask - Get the interrupt bit mask * @hba - Pointer to adapter instance @@ -612,7 +652,7 @@ static void ufshcd_prepare_req_desc(struct ufshcd_lrb *lrbp, u32 *upiu_flags) { struct utp_transfer_req_desc *req_desc = lrbp-utr_descriptor_ptr; enum dma_data_direction cmd_dir = - lrbp-cmd-sc_data_direction; + lrbp-cmd ? lrbp-cmd-sc_data_direction : DMA_NONE; u32 data_direction; u32 dword_0; @@ -629,6 +669,8 @@ static void ufshcd_prepare_req_desc(struct ufshcd_lrb *lrbp, u32 *upiu_flags) dword_0 = data_direction | (lrbp-command_type UPIU_COMMAND_TYPE_OFFSET); + if (lrbp-intr_cmd) + dword_0 |= UTP_REQ_DESC_INT_CMD; /* Transfer request descriptor header fields */ req_desc-header.dword_0 = cpu_to_le32(dword_0); @@ -717,6 +759,18 @@ static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba, } +static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp) +{ + struct utp_upiu_req *ucd_req_ptr = lrbp-ucd_req_ptr; + + memset(ucd_req_ptr, 0, sizeof(struct utp_upiu_req)); + + /* command descriptor fields */ + ucd_req_ptr-header.dword_0 = + UPIU_HEADER_DWORD( + UPIU_TRANSACTION_NOP_OUT, 0, 0, lrbp-task_tag); +} + /** * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU) * @hba - UFS hba @@ -731,11 +785,13 @@ static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) case UTP_CMD_TYPE_SCSI: case UTP_CMD_TYPE_DEV_MANAGE: ufshcd_prepare_req_desc(lrbp, upiu_flags); - if (lrbp-command_type == UTP_CMD_TYPE_SCSI) + if (lrbp-cmd lrbp-command_type == UTP_CMD_TYPE_SCSI) ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags); - else + else if (lrbp-cmd ufshcd_is_query_req(lrbp)) ufshcd_prepare_utp_query_req_upiu(hba, lrbp, upiu_flags); + else if (!lrbp-cmd) + ufshcd_prepare_utp_nop_upiu(lrbp); break; case UTP_CMD_TYPE_UFS: /* For UFS native command implementation */ @@ -784,6 +840,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp-sense_buffer = cmd-sense_buffer; lrbp-task_tag = tag; lrbp-lun = cmd-device-lun; + lrbp-intr_cmd = false; if (ufshcd_is_query_req(lrbp)) lrbp-command_type = UTP_CMD_TYPE_DEV_MANAGE; @@ -972,6 +1029,104 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) return
[PATCH V2 1/9] scsi: ufs: add support for query requests
Add support for sending UFS query requests through tagged command queuing. This design allows queuing query requests in any open slot along with other SCSI commands. In this way there is no need to save a slot in the requests queue and decrease its size. A query request is posing to a SCSI command to use native flow. But unlike normal SCSI command flow, the data and response fields are filled in UFS host data structure instead of passing as arguments while queuing into SCSI mlqueue (mid-layer SCSI queue, the requests from this queue are submitted to the device queue). As per specification only one query request is allowed to be processed by device. Hence a mutex lock for protecting data and response fields (hba-query.request and hba-query.response) needs to be held while query request is in progress. The API for submitting a query request is ufs_query_request() in ufshcd.c. This function is responsible for: 1. Obtaining the SCSI device from the host 2. Keeping the query mutex to prevent multiple queries 3. Storing the required data for sending a query request in ufs_hba 4. Queuing a SCSI vendor specific command to trigger a query request in the UFS driver. The callers of ufs_query_request() are expected to fill the query command data fields and are to provide an allocated response field for the driver to fill response fields after request completion. The request and response upiu is extended in a union to enable using the same data structure, both for command upiu and query request upiu. The query request flow is separated from the scsi command flow in: 1. Preparing the request 2. Validating response (error) codes 3. Copying data (only used for descriptor read/write query requests) 4. Copying response/sense Data error can't be handled in the scsi command native flow. Hence, we pass the code as without a change back to the submitting layer. UPIU (UFS Protocol Information Unit) size is increased to 512 bytes from 128. The UPIU header and the transaction specific fields (SCSI command or Query Request OSF - Op-code Specific Fields) are 32 bytes together, the rest is used to transfer extra request data (such as descriptor in query requests). In order to accommodate the largest descriptor in the UFS spec (256 bytes) we need to increase the UPIU size. Signed-off-by: Dolev Raviv dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 139bc06..086ff03 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -36,10 +36,20 @@ #ifndef _UFS_H #define _UFS_H +#include linux/mutex.h +#include linux/types.h + #define MAX_CDB_SIZE 16 +#define GENERAL_UPIU_REQUEST_SIZE 32 +#define UPIU_HEADER_DATA_SEGMENT_MAX_SIZE ((ALIGNED_UPIU_SIZE) - \ + (GENERAL_UPIU_REQUEST_SIZE)) +#define QUERY_OSF_SIZE ((GENERAL_UPIU_REQUEST_SIZE) - \ + (sizeof(struct utp_upiu_header))) +#define UFS_QUERY_RESERVED_SCSI_CMD 0xCC +#define UFS_QUERY_CMD_SIZE 10 #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ - ((byte3 24) | (byte2 16) |\ + cpu_to_be32((byte3 24) | (byte2 16) |\ (byte1 8) | (byte0)) /* @@ -62,7 +72,7 @@ enum { UPIU_TRANSACTION_COMMAND= 0x01, UPIU_TRANSACTION_DATA_OUT = 0x02, UPIU_TRANSACTION_TASK_REQ = 0x04, - UPIU_TRANSACTION_QUERY_REQ = 0x26, + UPIU_TRANSACTION_QUERY_REQ = 0x16, }; /* UTP UPIU Transaction Codes Target to Initiator */ @@ -73,6 +83,7 @@ enum { UPIU_TRANSACTION_TASK_RSP = 0x24, UPIU_TRANSACTION_READY_XFER = 0x31, UPIU_TRANSACTION_QUERY_RSP = 0x36, + UPIU_TRANSACTION_REJECT_UPIU= 0x3F, }; /* UPIU Read/Write flags */ @@ -90,6 +101,12 @@ enum { UPIU_TASK_ATTR_ACA = 0x03, }; +/* UPIU Query request function */ +enum { + UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01, + UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81, +}; + /* UTP QUERY Transaction Specific Fields OpCode */ enum { UPIU_QUERY_OPCODE_NOP = 0x0, @@ -103,6 +120,21 @@ enum { UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN= 0xFD, + QUERY_RESULT_INVALID_OPCODE = 0xFE, + QUERY_RESULT_GENERAL_FAILURE= 0xFF, +}; + /* UTP Transfer Request Command Type
[PATCH V2 4/9] scsi: ufs: wrap the i/o access operations
Simplify operations with hiding mmio_base. Signed-off-by: Seungwon Jeon tgih@samsung.com Tested-by: Maya Erez me...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7ce40a5..3946b9d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -71,7 +71,7 @@ enum { */ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) { - return readl(hba-mmio_base + REG_UFS_VERSION); + return ufshcd_readl(hba, REG_UFS_VERSION); } /** @@ -130,8 +130,7 @@ static inline int ufshcd_get_tm_free_slot(struct ufs_hba *hba) */ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) { - writel(~(1 pos), - (hba-mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR)); + ufshcd_writel(hba, ~(1 pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR); } /** @@ -165,7 +164,7 @@ static inline int ufshcd_get_lists_status(u32 reg) */ static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba) { - return readl(hba-mmio_base + REG_UIC_COMMAND_ARG_2) + return ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2) MASK_UIC_COMMAND_RESULT; } @@ -238,18 +237,15 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option) { switch (option) { case INT_AGGR_RESET: - writel((INT_AGGR_ENABLE | - INT_AGGR_COUNTER_AND_TIMER_RESET), - (hba-mmio_base + -REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); + ufshcd_writel(hba, INT_AGGR_ENABLE | + INT_AGGR_COUNTER_AND_TIMER_RESET, + REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); break; case INT_AGGR_CONFIG: - writel((INT_AGGR_ENABLE | - INT_AGGR_PARAM_WRITE | - INT_AGGR_COUNTER_THRESHOLD_VALUE | - INT_AGGR_TIMEOUT_VALUE), - (hba-mmio_base + -REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); + ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE | + INT_AGGR_COUNTER_THRESHOLD_VALUE | + INT_AGGR_TIMEOUT_VALUE, + REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); break; } } @@ -262,12 +258,10 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option) */ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) { - writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT, - (hba-mmio_base + - REG_UTP_TASK_REQ_LIST_RUN_STOP)); - writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT, - (hba-mmio_base + - REG_UTP_TRANSFER_REQ_LIST_RUN_STOP)); + ufshcd_writel(hba, UTP_TASK_REQ_LIST_RUN_STOP_BIT, + REG_UTP_TASK_REQ_LIST_RUN_STOP); + ufshcd_writel(hba, UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT, + REG_UTP_TRANSFER_REQ_LIST_RUN_STOP); } /** @@ -276,7 +270,7 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) */ static inline void ufshcd_hba_start(struct ufs_hba *hba) { - writel(CONTROLLER_ENABLE , (hba-mmio_base + REG_CONTROLLER_ENABLE)); + ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE); } /** @@ -287,7 +281,7 @@ static inline void ufshcd_hba_start(struct ufs_hba *hba) */ static inline int ufshcd_is_hba_active(struct ufs_hba *hba) { - return (readl(hba-mmio_base + REG_CONTROLLER_ENABLE) 0x1) ? 0 : 1; + return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE) 0x1) ? 0 : 1; } /** @@ -299,8 +293,7 @@ static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { __set_bit(task_tag, hba-outstanding_reqs); - writel((1 task_tag), - (hba-mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL)); + ufshcd_writel(hba, 1 task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); } /** @@ -381,8 +374,7 @@ void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) */ static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) { - hba-capabilities = - readl(hba-mmio_base + REG_CONTROLLER_CAPABILITIES); + hba-capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES); /* nutrs and nutmrs are 0 based values */ hba-nutrs = (hba-capabilities MASK_TRANSFER_REQUESTS_SLOTS) + 1; @@ -399,16 +391,13 @@ static inline void ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd) { /* Write Args */ - writel(uic_cmnd-argument1, - (hba-mmio_base + REG_UIC_COMMAND_ARG_1)); - writel(uic_cmnd-argument2, - (hba-mmio_base + REG_UIC_COMMAND_ARG_2)); - writel(uic_cmnd-argument3, - (hba-mmio_base + REG_UIC_COMMAND_ARG_3)); + ufshcd_writel(hba, uic_cmnd-argument1, REG_UIC_COMMAND_ARG_1); + ufshcd_writel(hba, uic_cmnd-argument2,
[PATCH V2 5/9] scsi: ufs: amend interrupt configuration
It makes interrupt setting more flexible especially for disabling. And wrong bit mask is fixed for ver 1.0. [17:16] is added for mask. Signed-off-by: Seungwon Jeon tgih@samsung.com Tested-by: Maya Erez me...@codeaurora.org Acked-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3946b9d..c342a38 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -35,6 +35,10 @@ #include ufshcd.h +#define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\ +UTP_TASK_REQ_COMPL |\ +UFSHCD_ERROR_MASK) + enum { UFSHCD_MAX_CHANNEL = 0, UFSHCD_MAX_ID = 1, @@ -64,6 +68,20 @@ enum { }; /** + * ufshcd_get_intr_mask - Get the interrupt bit mask + * @hba - Pointer to adapter instance + * + * Returns interrupt bit mask per version + */ +static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) +{ + if (hba-ufs_version == UFSHCI_VERSION_10) + return INTERRUPT_MASK_ALL_VER_10; + else + return INTERRUPT_MASK_ALL_VER_11; +} + +/** * ufshcd_get_ufs_version - Get the UFS version supported by the HBA * @hba - Pointer to adapter instance * @@ -441,25 +459,45 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) } /** - * ufshcd_int_config - enable/disable interrupts + * ufshcd_enable_intr - enable interrupts * @hba: per adapter instance - * @option: interrupt option + * @intrs: interrupt bits */ -static void ufshcd_int_config(struct ufs_hba *hba, u32 option) +static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs) { - switch (option) { - case UFSHCD_INT_ENABLE: - ufshcd_writel(hba, hba-int_enable_mask, REG_INTERRUPT_ENABLE); - break; - case UFSHCD_INT_DISABLE: - if (hba-ufs_version == UFSHCI_VERSION_10) - ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10, - REG_INTERRUPT_ENABLE); - else - ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11, - REG_INTERRUPT_ENABLE); - break; + u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + + if (hba-ufs_version == UFSHCI_VERSION_10) { + u32 rw; + rw = set INTERRUPT_MASK_RW_VER_10; + set = rw | ((set ^ intrs) intrs); + } else { + set |= intrs; + } + + ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE); +} + +/** + * ufshcd_disable_intr - disable interrupts + * @hba: per adapter instance + * @intrs: interrupt bits + */ +static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) +{ + u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); + + if (hba-ufs_version == UFSHCI_VERSION_10) { + u32 rw; + rw = (set INTERRUPT_MASK_RW_VER_10) + ~(intrs INTERRUPT_MASK_RW_VER_10); + set = rw | ((set intrs) ~INTERRUPT_MASK_RW_VER_10); + + } else { + set = ~intrs; } + + ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE); } /** @@ -842,8 +880,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba) uic_cmd-argument3 = 0; /* enable UIC related interrupts */ - hba-int_enable_mask |= UIC_COMMAND_COMPL; - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); + ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); /* sending UIC commands to controller */ ufshcd_send_uic_command(hba, uic_cmd); @@ -890,13 +927,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) } /* Enable required interrupts */ - hba-int_enable_mask |= (UTP_TRANSFER_REQ_COMPL | -UIC_ERROR | -UTP_TASK_REQ_COMPL | -DEVICE_FATAL_ERROR | -CONTROLLER_FATAL_ERROR | -SYSTEM_BUS_FATAL_ERROR); - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); + ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); /* Configure interrupt aggregation */ ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); @@ -1724,7 +1755,7 @@ static void ufshcd_hba_free(struct ufs_hba *hba) void ufshcd_remove(struct ufs_hba *hba) { /* disable interrupts */ - ufshcd_int_config(hba, UFSHCD_INT_DISABLE); + ufshcd_disable_intr(hba, hba-intr_mask); ufshcd_hba_stop(hba); ufshcd_hba_free(hba); @@ -1782,6 +1813,9 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle, /* Get UFS version supported by the controller */ hba-ufs_version = ufshcd_get_ufs_version(hba); + /* Get Interrupt bit mask per version */ + hba-intr_mask = ufshcd_get_intr_mask(hba); + /* Allocate memory for host memory space */ err = ufshcd_memory_alloc(hba); if (err) {
[PATCH V2 3/9] scsi: ufs: Fix the response UPIU length setting
The response UPIU length should be in DWORD and not in bytes. Signed-off-by: Maya Erez me...@codeaurora.org Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org Tested-by: Dolev Raviv dra...@codeaurora.org diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 4ddc8be..7ce40a5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -807,7 +807,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba) utrdlp[i].prd_table_offset = cpu_to_le16((prdt_offset 2)); utrdlp[i].response_upiu_length = - cpu_to_le16(ALIGNED_UPIU_SIZE); + cpu_to_le16(ALIGNED_UPIU_SIZE 2); hba-lrb[i].utr_descriptor_ptr = (utrdlp + i); hba-lrb[i].ucd_req_ptr = -- 1.7.6 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 0/9] ufs patch siries
This patch series clusters the latest version of all the UFS patches in the SCSI mailing list. It gives a stable functional base line for the UFS driver. It includes the following versions: [PATCH V5] scsi: ufs: add support for query requests [PATCH 1/2] Documentation: devicetree: Add DT bindings for UFS host controller [PATCH 2/2] scsi: ufs: Fix the response UPIU length setting [PATCH v4 1/6] scsi: ufs: wrap the i/o access operations [PATCH v4 2/6] scsi: ufs: amend interrupt configuration [PATCH v4 3/6] scsi: ufs: fix interrupt status clears [PATCH v4 4/6] scsi: ufs: rework link start-up process [PATCH V5 1/1] scsi: ufs: Add support for sending NOP OUT UPIU [PATCH V4] scsi: ufs: Set fDeviceInit flag to initiate device initialization But does not include: [PATCH v4 5/6] scsi: ufs: add dme configuration primit [PATCH v4 6/6] scsi: ufs: add dme control primitives -- V2: - Add query requst support patch which was ommited from the merge window Dolev Raviv (9): scsi: ufs: add support for query requests Documentation: devicetree: Add DT bindings for UFS host controller scsi: ufs: Fix the response UPIU length setting scsi: ufs: wrap the i/o access operations scsi: ufs: amend interrupt configuration scsi: ufs: fix interrupt status clears scsi: ufs: rework link start-up process scsi: ufs: Add support for sending NOP OUT UPIU scsi: ufs: Set fDeviceInit flag to initiate device initialization .../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 16 + drivers/scsi/ufs/ufs.h | 132 ++- drivers/scsi/ufs/ufshcd.c | 1172 +++- drivers/scsi/ufs/ufshcd.h | 47 +- drivers/scsi/ufs/ufshci.h |7 +- 5 files changed, 1101 insertions(+), 273 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt -- 1.7.6 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds()
From 18072c1c3506a7e37ee485307a2c343efe5af4d0 Mon Sep 17 00:00:00 2001 From: Gu Zheng guz.f...@cn.fujitsu.com Date: Mon, 13 May 2013 15:45:24 +0900 Subject: [PATCH 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds() Introduce a new timestamp function local_time_seconds() to hide the conversion of system time in UTC to local time seconds. Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- include/linux/time.h |1 + kernel/time.c| 11 +++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/include/linux/time.h b/include/linux/time.h index 22d81b3..1aec534 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -271,4 +271,5 @@ static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) a-tv_nsec = ns; } +extern u32 local_time_seconds(void); #endif diff --git a/kernel/time.c b/kernel/time.c index d3617db..715377d 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -712,3 +712,14 @@ struct timespec timespec_add_safe(const struct timespec lhs, return res; } + +/* + * Convert system time in UTC to local time seconds. + */ +u32 local_time_seconds(void) +{ + struct timeval utc; + do_gettimeofday(utc); + return (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); +} +EXPORT_SYMBOL(local_time_seconds); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] driver/scsi: Use local_time_seconds() to simplify the get local timestamp operation
From 1abbcf9fa5ce6c9a0b005a445c53b9412b42fa83 Mon Sep 17 00:00:00 2001 From: Gu Zheng guz.f...@cn.fujitsu.com Date: Mon, 13 May 2013 14:58:49 +0900 Subject: [PATCH 2/2] driver/scsi: Use local_time_seconds() to simplify the get local timestamp operation Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- drivers/scsi/3w-9xxx.c | 14 ++ drivers/scsi/3w-sas.c | 14 ++ 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 5e1e12c..44b3ea8 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -374,8 +374,6 @@ out: /* This function will queue an event */ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header) { - u32 local_time; - struct timeval time; TW_Event *event; unsigned short aen; char host[16]; @@ -398,9 +396,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H memset(event, 0, sizeof(TW_Event)); event-severity = TW_SEV_OUT(header-status_block.severity__reserved); - do_gettimeofday(time); - local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60)); - event-time_stamp_sec = local_time; + event-time_stamp_sec = local_time_seconds(); event-aen_code = aen; event-retrieved = TW_AEN_NOT_RETRIEVED; event-sequence_id = tw_dev-error_sequence_id; @@ -479,11 +475,9 @@ out: static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) { u32 schedulertime; - struct timeval utc; TW_Command_Full *full_command_packet; TW_Command *command_packet; TW_Param_Apache *param; - u32 local_time; /* Fill out the command packet */ full_command_packet = tw_dev-command_packet_virt[request_id]; @@ -503,11 +497,7 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) param-parameter_id = cpu_to_le16(0x3); /* SchedulerTime */ param-parameter_size_bytes = cpu_to_le16(4); - /* Convert system time in UTC to local time seconds since last - Sunday 12:00AM */ - do_gettimeofday(utc); - local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); - schedulertime = local_time - (3 * 86400); + schedulertime = local_time_seconds() - (3 * 86400); schedulertime = cpu_to_le32(schedulertime % 604800); memcpy(param-data, schedulertime, sizeof(u32)); diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index c845bdb..69f1d8a 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -236,8 +236,6 @@ out: /* This function will queue an event */ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header) { - u32 local_time; - struct timeval time; TW_Event *event; unsigned short aen; char host[16]; @@ -256,9 +254,7 @@ static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H memset(event, 0, sizeof(TW_Event)); event-severity = TW_SEV_OUT(header-status_block.severity__reserved); - do_gettimeofday(time); - local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60)); - event-time_stamp_sec = local_time; + event-time_stamp_sec = local_time_seconds(); event-aen_code = aen; event-retrieved = TW_AEN_NOT_RETRIEVED; event-sequence_id = tw_dev-error_sequence_id; @@ -444,11 +440,9 @@ out: static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) { u32 schedulertime; - struct timeval utc; TW_Command_Full *full_command_packet; TW_Command *command_packet; TW_Param_Apache *param; - u32 local_time; /* Fill out the command packet */ full_command_packet = tw_dev-command_packet_virt[request_id]; @@ -468,11 +462,7 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id) param-parameter_id = cpu_to_le16(0x3); /* SchedulerTime */ param-parameter_size_bytes = cpu_to_le16(4); - /* Convert system time in UTC to local time seconds since last - Sunday 12:00AM */ - do_gettimeofday(utc); - local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60)); - schedulertime = local_time - (3 * 86400); + schedulertime = local_time_seconds() - (3 * 86400); schedulertime = cpu_to_le32(schedulertime % 604800); memcpy(param-data, schedulertime, sizeof(u32)); -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH V1 0/8] ufs patch siries
Yes, apparently I have, and I missed this mail as well until it was brought to my attention earlier. I apologise for re sending the patch series with mistakes, I withdraw it and let Santosh send it as he see fit. On Monday, May 13, 2013, Dolev Raviv wrote: This patch series clusters the latest version of all the UFS patches in the SCSI mailing list. It gives a stable functional base line for the UFS driver. It includes the following versions: [PATCH 1/2] Documentation: devicetree: Add DT bindings for UFS host controller [PATCH 2/2] scsi: ufs: Fix the response UPIU length setting [PATCH v4 1/6] scsi: ufs: wrap the i/o access operations [PATCH v4 2/6] scsi: ufs: amend interrupt configuration [PATCH v4 3/6] scsi: ufs: fix interrupt status clears [PATCH v4 4/6] scsi: ufs: rework link start-up process [PATCH V5 1/1] scsi: ufs: Add support for sending NOP OUT UPIU [PATCH V4] scsi: ufs: Set fDeviceInit flag to initiate device initialization But does not include: [PATCH v4 5/6] scsi: ufs: add dme configuration primit [PATCH v4 6/6] scsi: ufs: add dme control primitives Dolev Raviv (8): Documentation: devicetree: Add DT bindings for UFS host controller scsi: ufs: Fix the response UPIU length setting scsi: ufs: wrap the i/o access operations scsi: ufs: amend interrupt configuration scsi: ufs: fix interrupt status clears scsi: ufs: rework link start-up process scsi: ufs: Add support for sending NOP OUT UPIU scsi: ufs: Set fDeviceInit flag to initiate device initialization It seems that you missed my first comment on previous mailing. RE: [PATCH V1 3/8] scsi: ufs: wrap the i/o access operations Could you check the e-mail? If you intended to sort the patches instead of Santosh, you should have identify the author per patch e-mail expect 8/8 which is from you. 'From: Author name Author e-mail' is expected in the head of e-mail. I feel that maintainer has this role, though. And there is need to check the base of tree for ufshcd. ' scsi: ufs: add support for query requests' is not merged finally. I think we can talk with Santosh for those. Thanks, Seungwon Jeon -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
On 05/14/2013 01:23 AM, Yinghai Lu wrote: On Mon, May 13, 2013 at 9:08 AM, Jiang Liu liu...@gmail.com wrote: From: Gu Zheng guz.f...@cn.fujitsu.com diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4f0bc0a..bc075a3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1131,6 +1131,7 @@ static void pci_release_dev(struct device *dev) struct pci_dev *pci_dev; pci_dev = to_pci_dev(dev); + pci_bus_put(pci_dev-bus); pci_release_capabilities(pci_dev); pci_release_of_node(pci_dev); kfree(pci_dev); @@ -1269,11 +1270,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) if (!pci_bus_read_dev_vendor_id(bus, devfn, l, 60*1000)) return NULL; - dev = alloc_pci_dev(); + dev = pci_alloc_dev(bus); if (!dev) return NULL; - dev-bus = bus; dev-devfn = devfn; dev-vendor = l 0x; dev-device = (l 16) 0x; in pci_setup_device() fail path, it release the ref to that bus. Yes, you're right, we need to release the bus' ref if pci_setup_device() failed. Thanks for your correction.:) Best regards, Gu Yinghai From 7add6d9e70919b95be2debde2f58fc31d26c75bf Mon Sep 17 00:00:00 2001 From: Gu Zheng guz.f...@cn.fujitsu.com Date: Tue, 14 May 2013 16:11:07 +0800 Subject: [PATCH v3] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead v3: Follow Yinghai's correction to release the bus' ref in pci_setup_device() fail path. v2: Follow Bjorn's correction to move pci_bus_put() to pci_release_dev() instead. Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- arch/powerpc/kernel/pci_of_scan.c |3 +-- arch/sparc/kernel/pci.c |3 +-- drivers/char/agp/alpha-agp.c |2 +- drivers/char/agp/parisc-agp.c |2 +- drivers/pci/iov.c |8 +--- drivers/pci/probe.c |5 +++-- drivers/scsi/megaraid.c |2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 2a67e9b..24d01c4 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, const char *type; struct pci_slot *slot; - dev = alloc_pci_dev(); + dev = pci_alloc_dev(bus); if (!dev) return NULL; type = of_get_property(node, device_type, NULL); @@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, pr_debug(create device, devfn: %x, type: %s\n, devfn, type); - dev-bus = bus; dev-dev.of_node = of_node_get(node); dev-dev.parent = bus-bridge; dev-dev.bus = pci_bus_type; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index baf4366..e5871fb 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, const char *type; u32 class; - dev = alloc_pci_dev(); + dev = pci_alloc_dev(bus); if (!dev) return NULL; @@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, printk(create device, devfn: %x, type: %s\n, devfn, type); - dev-bus = bus; dev-sysdata = node; dev-dev.parent = bus-bridge; dev-dev.bus = pci_bus_type; diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index dd84af4..199b8e9 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c @@ -174,7 +174,7 @@ alpha_core_agp_setup(void) /* * Build a fake pci_dev struct */ - pdev = alloc_pci_dev(); + pdev = pci_alloc_dev(NULL); if (!pdev) return -ENOMEM; pdev-vendor = 0x; diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 94821ab..bf5d247 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c @@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) struct agp_bridge_data *bridge; int error = 0; - fake_bridge_dev = alloc_pci_dev(); + fake_bridge_dev = pci_alloc_dev(NULL); if (!fake_bridge_dev) { error = -ENOMEM; goto fail; diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index c93071d..2652ca0 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -75,18 +75,20 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) struct pci_dev *virtfn; struct resource *res; struct pci_sriov *iov = dev-sriov; + struct pci_bus *bus; - virtfn = alloc_pci_dev(); + virtfn = pci_alloc_dev(NULL); if (!virtfn) return
Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
On 05/14/2013 04:26 PM, Gu Zheng wrote: On 05/14/2013 01:23 AM, Yinghai Lu wrote: On Mon, May 13, 2013 at 9:08 AM, Jiang Liu liu...@gmail.com wrote: From: Gu Zheng guz.f...@cn.fujitsu.com diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4f0bc0a..bc075a3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1131,6 +1131,7 @@ static void pci_release_dev(struct device *dev) struct pci_dev *pci_dev; pci_dev = to_pci_dev(dev); + pci_bus_put(pci_dev-bus); pci_release_capabilities(pci_dev); pci_release_of_node(pci_dev); kfree(pci_dev); @@ -1269,11 +1270,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) if (!pci_bus_read_dev_vendor_id(bus, devfn, l, 60*1000)) return NULL; - dev = alloc_pci_dev(); + dev = pci_alloc_dev(bus); if (!dev) return NULL; - dev-bus = bus; dev-devfn = devfn; dev-vendor = l 0x; dev-device = (l 16) 0x; in pci_setup_device() fail path, it release the ref to that bus. Yes, you're right, we need to release the bus' ref if pci_setup_device() failed. Hi Zheng, I suggest to use pci_release_dev() instead because it also needs to release OF related resources. I will update it in next version. diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bc075a3..2ac6338 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus pci_set_of_node(dev); if (pci_setup_device(dev)) { - kfree(dev); + pci_release_dev(dev-dev); return NULL; } hanks for your correction.:) Best regards, Gu Yinghai -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote: On 05/14/2013 04:26 PM, Gu Zheng wrote: I suggest to use pci_release_dev() instead because it also needs to release OF related resources. I will update it in next version. diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bc075a3..2ac6338 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus pci_set_of_node(dev); if (pci_setup_device(dev)) { - kfree(dev); + pci_release_dev(dev-dev); return NULL; no, should move pci_set_of_node calling into pci_setup_device. Yinghai -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds()
On 05/14/2013 12:45 AM, Gu Zheng wrote: From 18072c1c3506a7e37ee485307a2c343efe5af4d0 Mon Sep 17 00:00:00 2001 From: Gu Zheng guz.f...@cn.fujitsu.com Date: Mon, 13 May 2013 15:45:24 +0900 Subject: [PATCH 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds() Introduce a new timestamp function local_time_seconds() to hide the conversion of system time in UTC to local time seconds. So, why is this useful/needed? thanks -john -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] UFSHCD updates
Hi James, Please merge the following patches to scsi tree. Thanks, Santosh Geert Uytterhoeven (1): SCSI_UFSHCD should depend on SCSI_DMA Sachin Kamat (1): ufs: Remove redundant platform_set_drvdata() Sujit Reddy Thumma (1): Documentation: devicetree: Add DT bindings for UFS host controller Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | 16 drivers/scsi/ufs/Kconfig| 2 +- drivers/scsi/ufs/ufshcd-pltfrm.c| 1 - 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt -- 1.8.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] ufs: Remove redundant platform_set_drvdata()
From: Sachin Kamat sachin.ka...@linaro.org Commit 0998d06310 (device-core: Ensure drvdata = NULL when no driver is bound) removes the need to set driver data field to NULL. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org Signed-off-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 03319ac..3db2ee1 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -184,7 +184,6 @@ static int ufshcd_pltfrm_remove(struct platform_device *pdev) mem_size = resource_size(mem_res); release_mem_region(mem_res-start, mem_size); } - platform_set_drvdata(pdev, NULL); return 0; } -- 1.8.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] SCSI_UFSHCD should depend on SCSI_DMA
From: Geert Uytterhoeven ge...@linux-m68k.org If NO_DMA=y: drivers/built-in.o: In function `ufshcd_transfer_req_compl': drivers/scsi/ufs/ufshcd.c:1182: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_map_sg': drivers/scsi/ufs/ufshcd.c:377: undefined reference to `scsi_dma_map' drivers/built-in.o: In function `ufshcd_do_reset': drivers/scsi/ufs/ufshcd.c:912: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_memory_alloc': drivers/scsi/ufs/ufshcd.c:565: undefined reference to `dma_alloc_coherent' drivers/built-in.o: In function `ufshcd_free_hba_memory': drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:199: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent' drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent' drivers/built-in.o:drivers/scsi/ufs/ufshcd.c:199: more undefined references to `dma_free_coherent' follow drivers/built-in.o: In function `ufshcd_abort': drivers/scsi/ufs/ufshcd.c:1498: undefined reference to `scsi_dma_unmap' drivers/built-in.o: In function `ufshcd_device_reset': drivers/scsi/ufs/ufshcd.c:1436: undefined reference to `scsi_dma_unmap' Signed-off-by: Geert Uytterhoeven ge...@linux-m68k.org Cc: Vinayak Holikatti vinholika...@gmail.com Cc: James E.J. Bottomley jbottom...@parallels.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Santosh Y santos...@gmail.com diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 35faf24..f07f901 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -34,7 +34,7 @@ config SCSI_UFSHCD tristate Universal Flash Storage Controller Driver Core - depends on SCSI + depends on SCSI SCSI_DMA ---help--- This selects the support for UFS devices in Linux, say Y and make sure that you know the name of your UFS host adapter (the card -- 1.8.1.2 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
On Tue 14 May 2013 11:10:33 PM CST, Yinghai Lu wrote: On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote: On 05/14/2013 04:26 PM, Gu Zheng wrote: I suggest to use pci_release_dev() instead because it also needs to release OF related resources. I will update it in next version. diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bc075a3..2ac6338 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus pci_set_of_node(dev); if (pci_setup_device(dev)) { - kfree(dev); + pci_release_dev(dev-dev); return NULL; no, should move pci_set_of_node calling into pci_setup_device. Yinghai I'm not sure whether we should call pci_set_of_node() for SR-IOV devices too, any suggestions here? -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 2/9] Documentation: devicetree: Add DT bindings for UFS host controller
On Tue, May 14, 2013 at 12:08 AM, Dolev Raviv dra...@codeaurora.org wrote: Compatible list is used in commit 03b1781 but is not documented. Add necessary device tree bindings to describe on-chip UFS host controllers. Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt new file mode 100644 index 000..20468b2 --- /dev/null +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -0,0 +1,16 @@ +* Universal Flash Storage (UFS) Host Controller + +UFSHC nodes are defined to describe on-chip UFS host controllers. +Each UFS controller instance should have its own node. + +Required properties: +- compatible: compatible list, contains jedec,ufs-1.1 +- interrupts: interrupt mapping for UFS host controller IRQ +- reg : registers mapping + +Example: + ufshc@0xfc598000 { + compatible = jedec,ufs-1.1; Hmm. Does jedec really specify the programming interface of this type of device, register layout and meaning? It seems to be more about the command set and electrical/connectivity specifications, no? -Olof -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead
On Tue, May 14, 2013 at 9:57 AM, Liu Jiang liu...@gmail.com wrote: On Tue 14 May 2013 11:10:33 PM CST, Yinghai Lu wrote: On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote: On 05/14/2013 04:26 PM, Gu Zheng wrote: I suggest to use pci_release_dev() instead because it also needs to release OF related resources. I will update it in next version. diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bc075a3..2ac6338 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus pci_set_of_node(dev); if (pci_setup_device(dev)) { - kfree(dev); + pci_release_dev(dev-dev); return NULL; no, should move pci_set_of_node calling into pci_setup_device. Yinghai I'm not sure whether we should call pci_set_of_node() for SR-IOV devices too, any suggestions here? or just move down pci_set_of_node after pci_setup_device? anyway that is another bug. Yinghai -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: SCSI testing/USB devices are amazing
Ronnie == ronnie sahlberg ronniesahlb...@gmail.com writes: Ronnie, Ronnie I have added tests for the block limits VPD as Ronnie SCSI.Inquiry.InquiryBlockLimits. It checks that the pagelength Ronnie is valid. 3C if SBC3 is claimed and 0C if prior to SBC3. Well, there are devices out there that claim SPC3/SBC2 compliance but do support some of the newer features from SPC4/SBC3. In this case I'd rely on the supported VPD page list. And if the BL VPD is present and the device reports SPC3/SBC2 I'd print a warning. Ronnie It then validates that the UNMAP counts are sane. Sane being Ronnie that if LBPU==0 then these must be 0, and if LBPU==1 then these Ronnie must be 1, must be than 2**LBPPBE and either 0x or Ronnie 1M. (1M is arbitrary for crazy large number of blocks) That's a good start, anyway. Ronnie The other fields I had a hard time to come up with good sanity Ronnie tests for. Any suggestions ? Do you have examples of things Ronnie that vendors get wrong here ? Maximum Write Same Length vs. support for WS10 and WS16. Another interesting Write Same test: I have several devices that support WS16 but which only support a 2-byte block count in WS16. I.e. you get the larger LBA but not a bigger block count with WS16. There's also the Logical Block Provisioning VPD page. You could verify that UNMAP is supported when LBPU=1. Repeat for LBPWS and LBPWS10. You could verify that the device actually returns zeroes when LBPRZ=1. Ronnie I will add tests for when protection information is enabled in Ronnie the future, I will need to find time to add it to tgt first. I have a fairly extensive set of PI tests in my test suite. But that gets pretty involved. We can deal with those later. Ronnie Very nice document. Section 1.3 could update Ronnie though. READCAPACITY16 is only mandatory in SBC-2 IF the device Ronnie supports protection information, but optional if it does not. Ronnie In SBC-3 it is always mandatory though. Thin provisioning and Ronnie different logical/physical block sizes were only added to this Ronnie command in SBC-3 not SBC-2. I describe what we actually do, not what's spec compliant :) This is our current heuristic for READ CAPACITY(16): static int sd_try_rc16_first(struct scsi_device *sdp) { if (sdp-host-max_cmd_len 16) return 0; if (sdp-scsi_level SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) return 1; return 0; } Ronnie I have thus updated my READCAPACITY16 tests so that IF SBC-3 is Ronnie claimed, or if IQN-PROTECT is set then the device must support Ronnie this opcode or the test will fail. Otherwise, if it is not Ronnie SBC-3 and if PROTECT is clear, then the test will be skipped but Ronnie not fail if the opcode is missing. *nod* -- Martin K. Petersen Oracle Linux Engineering -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html