Pull char/misc driver fixes from Greg KH: "Here are four small char/misc driver fixes for 5.19-rc6 to resolve some reported issues. They only affect two drivers: - rtsx_usb: fix for of-reported DMA warning error, the driver was handling memory buffers in odd ways, it has now been fixed up to be much simpler and correct by Shuah. - at25 eeprom driver bugfix for reported problem All of these have been in linux-next for a week with no reported problems" * tag 'char-misc-5.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: misc: rtsx_usb: set return value in rsp_buf alloc err path misc: rtsx_usb: use separate command and response buffers misc: rtsx_usb: fix use of dma mapped buffer for usb bulk transfer eeprom: at25: Rework buggy read splitting
Unified · Split
| @@ -631,16 +631,20 @@ static int rtsx_usb_probe(struct usb_interface *intf, · 630 unmodified lines | ||
| 631 | 631 | |
| 632 | 632 | ucr->pusb_dev = usb_dev; |
| 633 | 633 | |
| 634 | − ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE, | |
| 635 | − GFP_KERNEL, &ucr->iobuf_dma); | |
| 636 | − if (!ucr->iobuf) | |
| 634 | + ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); | |
| 635 | + if (!ucr->cmd_buf) | |
| 637 | 636 | return -ENOMEM; |
| 638 | 637 | |
| 638 | + ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); | |
| 639 | + if (!ucr->rsp_buf) { | |
| 640 | + ret = -ENOMEM; | |
| 641 | + goto out_free_cmd_buf; | |
| 642 | + } | |
| 643 | + | |
| 639 | 644 | usb_set_intfdata(intf, ucr); |
| 640 | 645 | |
| 641 | 646 | ucr->vendor_id = id->idVendor; |
| 642 | 647 | ucr->product_id = id->idProduct; |
| 643 | − ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf; | |
| 644 | 648 | |
| 645 | 649 | mutex_init(&ucr->dev_mutex); |
| 646 | 650 | |
| @@ -668,8 +672,11 @@ static int rtsx_usb_probe(struct usb_interface *intf, · 21 unmodified lines | ||
| 668 | 672 | |
| 669 | 673 | out_init_fail: |
| 670 | 674 | usb_set_intfdata(ucr->pusb_intf, NULL); |
| 671 | − usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | |
| 672 | − ucr->iobuf_dma); | |
| 675 | + kfree(ucr->rsp_buf); | |
| 676 | + ucr->rsp_buf = NULL; | |
| 677 | +out_free_cmd_buf: | |
| 678 | + kfree(ucr->cmd_buf); | |
| 679 | + ucr->cmd_buf = NULL; | |
| 673 | 680 | return ret; |
| 674 | 681 | } |
| 675 | 682 | |
| @@ -682,8 +689,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) · 6 unmodified lines | ||
| 682 | 689 | mfd_remove_devices(&intf->dev); |
| 683 | 690 | |
| 684 | 691 | usb_set_intfdata(ucr->pusb_intf, NULL); |
| 685 | − usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | |
| 686 | − ucr->iobuf_dma); | |
| 692 | + | |
| 693 | + kfree(ucr->cmd_buf); | |
| 694 | + ucr->cmd_buf = NULL; | |
| 695 | + | |
| 696 | + kfree(ucr->rsp_buf); | |
| 697 | + ucr->rsp_buf = NULL; | |
| 687 | 698 | } |
| 688 | 699 | |
| 689 | 700 | #ifdef CONFIG_PM |
| @@ -80,10 +80,9 @@ static int at25_ee_read(void *priv, unsigned int offset, · 79 unmodified lines | ||
| 80 | 80 | struct at25_data *at25 = priv; |
| 81 | 81 | char *buf = val; |
| 82 | 82 | size_t max_chunk = spi_max_transfer_size(at25->spi); |
| 83 | − size_t num_msgs = DIV_ROUND_UP(count, max_chunk); | |
| 84 | − size_t nr_bytes = 0; | |
| 85 | − unsigned int msg_offset; | |
| 86 | − size_t msg_count; | |
| 83 | + unsigned int msg_offset = offset; | |
| 84 | + size_t bytes_left = count; | |
| 85 | + size_t segment; | |
| 87 | 86 | u8 *cp; |
| 88 | 87 | ssize_t status; |
| 89 | 88 | struct spi_transfer t[2]; |
| @@ -97,9 +96,8 @@ static int at25_ee_read(void *priv, unsigned int offset, · 7 unmodified lines | ||
| 97 | 96 | if (unlikely(!count)) |
| 98 | 97 | return -EINVAL; |
| 99 | 98 | |
| 100 | − msg_offset = (unsigned int)offset; | |
| 101 | − msg_count = min(count, max_chunk); | |
| 102 | − while (num_msgs) { | |
| 99 | + do { | |
| 100 | + segment = min(bytes_left, max_chunk); | |
| 103 | 101 | cp = at25->command; |
| 104 | 102 | |
| 105 | 103 | instr = AT25_READ; |
| @@ -131,8 +129,8 @@ static int at25_ee_read(void *priv, unsigned int offset, · 25 unmodified lines | ||
| 131 | 129 | t[0].len = at25->addrlen + 1; |
| 132 | 130 | spi_message_add_tail(&t[0], &m); |
| 133 | 131 | |
| 134 | − t[1].rx_buf = buf + nr_bytes; | |
| 135 | − t[1].len = msg_count; | |
| 132 | + t[1].rx_buf = buf; | |
| 133 | + t[1].len = segment; | |
| 136 | 134 | spi_message_add_tail(&t[1], &m); |
| 137 | 135 | |
| 138 | 136 | status = spi_sync(at25->spi, &m); |
| @@ -142,10 +140,10 @@ static int at25_ee_read(void *priv, unsigned int offset, · 3 unmodified lines | ||
| 142 | 140 | if (status) |
| 143 | 141 | return status; |
| 144 | 142 | |
| 145 | − --num_msgs; | |
| 146 | − msg_offset += msg_count; | |
| 147 | − nr_bytes += msg_count; | |
| 148 | − } | |
| 143 | + msg_offset += segment; | |
| 144 | + buf += segment; | |
| 145 | + bytes_left -= segment; | |
| 146 | + } while (bytes_left > 0); | |
| 149 | 147 | |
| 150 | 148 | dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n", |
| 151 | 149 | count, offset); |
| @@ -229,7 +227,7 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) · 77 unmodified lines | ||
| 229 | 227 | do { |
| 230 | 228 | unsigned long timeout, retries; |
| 231 | 229 | unsigned segment; |
| 232 | − unsigned offset = (unsigned) off; | |
| 230 | + unsigned offset = off; | |
| 233 | 231 | u8 *cp = bounce; |
| 234 | 232 | int sr; |
| 235 | 233 | u8 instr; |
| @@ -54,8 +54,6 @@ struct rtsx_ucr { · 53 unmodified lines | ||
| 54 | 54 | struct usb_device *pusb_dev; |
| 55 | 55 | struct usb_interface *pusb_intf; |
| 56 | 56 | struct usb_sg_request current_sg; |
| 57 | − unsigned char *iobuf; | |
| 58 | − dma_addr_t iobuf_dma; | |
| 59 | 57 | |
| 60 | 58 | struct timer_list sg_timer; |
| 61 | 59 | struct mutex dev_mutex; |