diff options
Diffstat (limited to 'drivers/staging/rts5208/rtsx_transport.c')
-rw-r--r-- | drivers/staging/rts5208/rtsx_transport.c | 163 |
1 files changed, 87 insertions, 76 deletions
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c index f27491e..4d8e7c5 100644 --- a/drivers/staging/rts5208/rtsx_transport.c +++ b/drivers/staging/rts5208/rtsx_transport.c @@ -1,4 +1,5 @@ -/* Driver for Realtek PCI-Express card reader +/* + * Driver for Realtek PCI-Express card reader * * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. * @@ -30,74 +31,76 @@ * Scatter-gather transfer buffer access routines ***********************************************************************/ -/* Copy a buffer of length buflen to/from the srb's transfer buffer. +/* + * Copy a buffer of length buflen to/from the srb's transfer buffer. * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer * points to a list of s-g entries and we ignore srb->request_bufflen. * For non-scatter-gather transfers, srb->request_buffer points to the * transfer buffer itself and srb->request_bufflen is the buffer's length.) * Update the *index and *offset variables so that the next copy will - * pick up from where this one left off. */ + * pick up from where this one left off. + */ unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, - unsigned int *offset, enum xfer_buf_dir dir) + unsigned int buflen, + struct scsi_cmnd *srb, + unsigned int *index, + unsigned int *offset, + enum xfer_buf_dir dir) { unsigned int cnt; - /* If not using scatter-gather, just transfer the data directly. - * Make certain it will fit in the available buffer space. */ + /* If not using scatter-gather, just transfer the data directly. */ if (scsi_sg_count(srb) == 0) { + unsigned char *sgbuffer; + if (*offset >= scsi_bufflen(srb)) return 0; cnt = min(buflen, scsi_bufflen(srb) - *offset); + + sgbuffer = (unsigned char *)scsi_sglist(srb) + *offset; + if (dir == TO_XFER_BUF) - memcpy((unsigned char *) scsi_sglist(srb) + *offset, - buffer, cnt); + memcpy(sgbuffer, buffer, cnt); else - memcpy(buffer, (unsigned char *) scsi_sglist(srb) + - *offset, cnt); + memcpy(buffer, sgbuffer, cnt); *offset += cnt; - /* Using scatter-gather. We have to go through the list one entry + /* + * Using scatter-gather. We have to go through the list one entry * at a time. Each s-g entry contains some number of pages, and - * each page has to be kmap()'ed separately. If the page is already - * in kernel-addressable memory then kmap() will return its address. - * If the page is not directly accessible -- such as a user buffer - * located in high memory -- then kmap() will map it to a temporary - * position in the kernel's virtual address space. */ + * each page has to be kmap()'ed separately. + */ } else { struct scatterlist *sg = - (struct scatterlist *) scsi_sglist(srb) + (struct scatterlist *)scsi_sglist(srb) + *index; - /* This loop handles a single s-g list entry, which may + /* + * This loop handles a single s-g list entry, which may * include multiple pages. Find the initial page structure * and the starting offset within the page, and update - * the *offset and *index values for the next loop. */ + * the *offset and *index values for the next loop. + */ cnt = 0; while (cnt < buflen && *index < scsi_sg_count(srb)) { struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = - (sg->offset + *offset) & (PAGE_SIZE-1); + unsigned int poff = (sg->offset + *offset) & + (PAGE_SIZE - 1); unsigned int sglen = sg->length - *offset; if (sglen > buflen - cnt) { - /* Transfer ends within this s-g entry */ sglen = buflen - cnt; *offset += sglen; } else { - /* Transfer continues to next s-g entry */ *offset = 0; ++*index; ++sg; } - /* Transfer the data for all the pages in this - * s-g entry. For each page: call kmap(), do the - * transfer, and call kunmap() immediately after. */ while (sglen > 0) { unsigned int plen = min(sglen, (unsigned int) PAGE_SIZE - poff); @@ -122,10 +125,12 @@ unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, return cnt; } -/* Store the contents of buffer into srb's transfer buffer and set the -* SCSI residue. */ +/* + * Store the contents of buffer into srb's transfer buffer and set the + * SCSI residue. + */ void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; @@ -136,7 +141,7 @@ void rtsx_stor_set_xfer_buf(unsigned char *buffer, } void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; @@ -146,12 +151,12 @@ void rtsx_stor_get_xfer_buf(unsigned char *buffer, scsi_set_resid(srb, scsi_bufflen(srb) - buflen); } - /*********************************************************************** * Transport routines ***********************************************************************/ -/* Invoke the transport and basic error-handling/recovery methods +/* + * Invoke the transport and basic error-handling/recovery methods * * This is used to send the message to the device and receive the response. */ @@ -161,20 +166,21 @@ void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) result = rtsx_scsi_handler(srb, chip); - /* if the command gets aborted by the higher layers, we need to - * short-circuit all other processing + /* + * if the command gets aborted by the higher layers, we need to + * short-circuit all other processing. */ if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { dev_dbg(rtsx_dev(chip), "-- command was aborted\n"); srb->result = DID_ABORT << 16; - goto Handle_Errors; + goto handle_errors; } /* if there is a transport error, reset and don't auto-sense */ if (result == TRANSPORT_ERROR) { dev_dbg(rtsx_dev(chip), "-- transport indicates error, resetting\n"); srb->result = DID_ERROR << 16; - goto Handle_Errors; + goto handle_errors; } srb->result = SAM_STAT_GOOD; @@ -188,21 +194,18 @@ void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) /* set the result so the higher layers expect this data */ srb->result = SAM_STAT_CHECK_CONDITION; memcpy(srb->sense_buffer, - (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]), - sizeof(struct sense_data_t)); + (unsigned char *)&chip->sense_buffer[SCSI_LUN(srb)], + sizeof(struct sense_data_t)); } return; - /* Error and abort processing: try to resynchronize with the device - * by issuing a port reset. If that fails, try a class-specific - * device reset. */ -Handle_Errors: +handle_errors: return; } void rtsx_add_cmd(struct rtsx_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data) + u8 cmd_type, u16 reg_addr, u8 mask, u8 data) { u32 *cb = (u32 *)(chip->host_cmds_ptr); u32 val = 0; @@ -221,7 +224,7 @@ void rtsx_add_cmd(struct rtsx_chip *chip, void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) { - u32 val = 1 << 31; + u32 val = BIT(31); rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); @@ -235,7 +238,7 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) { struct rtsx_dev *rtsx = chip->rtsx; struct completion trans_done; - u32 val = 1 << 31; + u32 val = BIT(31); long timeleft; int err = 0; @@ -321,9 +324,11 @@ static inline void rtsx_add_sg_tbl( } static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, unsigned int *index, - unsigned int *offset, int size, - enum dma_data_direction dma_dir, int timeout) + struct scatterlist *sg, int num_sg, + unsigned int *index, + unsigned int *offset, int size, + enum dma_data_direction dma_dir, + int timeout) { struct rtsx_dev *rtsx = chip->rtsx; struct completion trans_done; @@ -334,7 +339,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, struct scatterlist *sg_ptr; u32 val = TRIG_DMA; - if ((sg == NULL) || (num_sg <= 0) || !offset || !index) + if (!sg || (num_sg <= 0) || !offset || !index) return -EIO; if (dma_dir == DMA_TO_DEVICE) @@ -363,15 +368,16 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + sg_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); resid = size; sg_ptr = sg; chip->sgi = 0; - /* Usually the next entry will be @sg@ + 1, but if this sg element + /* + * Usually the next entry will be @sg@ + 1, but if this sg element * is part of a chained scatterlist, it could jump to the start of * a new scatterlist array. So here we use sg_next to move to - * the proper sg + * the proper sg. */ for (i = 0; i < *index; i++) sg_ptr = sg_next(sg_ptr); @@ -476,7 +482,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, out: rtsx->done = NULL; rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); if (err < 0) rtsx_stop_cmd(chip, card); @@ -485,8 +491,9 @@ out: } static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - enum dma_data_direction dma_dir, int timeout) + struct scatterlist *sg, int num_sg, + enum dma_data_direction dma_dir, + int timeout) { struct rtsx_dev *rtsx = chip->rtsx; struct completion trans_done; @@ -496,7 +503,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, long timeleft; struct scatterlist *sg_ptr; - if ((sg == NULL) || (num_sg <= 0)) + if (!sg || (num_sg <= 0)) return -EIO; if (dma_dir == DMA_TO_DEVICE) @@ -525,7 +532,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, spin_unlock_irq(&rtsx->reg_lock); - buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + buf_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); sg_ptr = sg; @@ -623,7 +630,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, out: rtsx->done = NULL; rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); if (err < 0) rtsx_stop_cmd(chip, card); @@ -632,17 +639,18 @@ out: } static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, - size_t len, enum dma_data_direction dma_dir, int timeout) + size_t len, enum dma_data_direction dma_dir, + int timeout) { struct rtsx_dev *rtsx = chip->rtsx; struct completion trans_done; dma_addr_t addr; u8 dir; int err = 0; - u32 val = 1 << 31; + u32 val = BIT(31); long timeleft; - if ((buf == NULL) || (len <= 0)) + if (!buf || (len <= 0)) return -EIO; if (dma_dir == DMA_TO_DEVICE) @@ -652,8 +660,8 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, else return -ENXIO; - addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir); - if (!addr) + addr = dma_map_single(&rtsx->pci->dev, buf, len, dma_dir); + if (dma_mapping_error(&rtsx->pci->dev, addr)) return -ENOMEM; if (card == SD_CARD) @@ -706,7 +714,7 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, out: rtsx->done = NULL; rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir); + dma_unmap_single(&rtsx->pci->dev, addr, len, dma_dir); if (err < 0) rtsx_stop_cmd(chip, card); @@ -715,9 +723,9 @@ out: } int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, - void *buf, size_t len, int use_sg, unsigned int *index, - unsigned int *offset, enum dma_data_direction dma_dir, - int timeout) + void *buf, size_t len, int use_sg, + unsigned int *index, unsigned int *offset, + enum dma_data_direction dma_dir, int timeout) { int err = 0; @@ -725,13 +733,16 @@ int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) return -EIO; - if (use_sg) - err = rtsx_transfer_sglist_adma_partial(chip, card, - (struct scatterlist *)buf, use_sg, - index, offset, (int)len, dma_dir, timeout); - else + if (use_sg) { + struct scatterlist *sg = buf; + + err = rtsx_transfer_sglist_adma_partial(chip, card, sg, use_sg, + index, offset, (int)len, + dma_dir, timeout); + } else { err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); + } if (err < 0) { if (RTSX_TST_DELINK(chip)) { RTSX_CLR_DELINK(chip); @@ -744,7 +755,7 @@ int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, } int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, int timeout) + int use_sg, enum dma_data_direction dma_dir, int timeout) { int err = 0; @@ -756,8 +767,8 @@ int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, if (use_sg) { err = rtsx_transfer_sglist_adma(chip, card, - (struct scatterlist *)buf, - use_sg, dma_dir, timeout); + (struct scatterlist *)buf, + use_sg, dma_dir, timeout); } else { err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); } |