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 | ucr->pusb_dev = usb_dev; | 632 | ucr->pusb_dev = usb_dev; |
| 633 | 633 | ||
| 634 | ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE, | 634 | ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); |
| 635 | GFP_KERNEL, &ucr->iobuf_dma); | 635 | if (!ucr->cmd_buf) |
| 636 | if (!ucr->iobuf) | ||
| 637 | return -ENOMEM; | 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 | usb_set_intfdata(intf, ucr); | 644 | usb_set_intfdata(intf, ucr); |
| 640 | 645 | ||
| 641 | ucr->vendor_id = id->idVendor; | 646 | ucr->vendor_id = id->idVendor; |
| 642 | ucr->product_id = id->idProduct; | 647 | ucr->product_id = id->idProduct; |
| 643 | ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf; | ||
| 644 | 648 | ||
| 645 | mutex_init(&ucr->dev_mutex); | 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 | out_init_fail: | 673 | out_init_fail: |
| 670 | usb_set_intfdata(ucr->pusb_intf, NULL); | 674 | usb_set_intfdata(ucr->pusb_intf, NULL); |
| 671 | usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | 675 | kfree(ucr->rsp_buf); |
| 672 | ucr->iobuf_dma); | 676 | ucr->rsp_buf = NULL; |
| 677 | out_free_cmd_buf: | ||
| 678 | kfree(ucr->cmd_buf); | ||
| 679 | ucr->cmd_buf = NULL; | ||
| 673 | return ret; | 680 | return ret; |
| 674 | } | 681 | } |
| 675 | 682 | ||
| @@ -682,8 +689,12 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) · 6 unmodified lines | |||
| 682 | mfd_remove_devices(&intf->dev); | 689 | mfd_remove_devices(&intf->dev); |
| 683 | 690 | ||
| 684 | usb_set_intfdata(ucr->pusb_intf, NULL); | 691 | usb_set_intfdata(ucr->pusb_intf, NULL); |
| 685 | usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | 692 | |
| 686 | ucr->iobuf_dma); | 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 | #ifdef CONFIG_PM | 700 | #ifdef CONFIG_PM |
| @@ -80,10 +80,9 @@ static int at25_ee_read(void *priv, unsigned int offset, · 79 unmodified lines | |||
| 80 | struct at25_data *at25 = priv; | 80 | struct at25_data *at25 = priv; |
| 81 | char *buf = val; | 81 | char *buf = val; |
| 82 | size_t max_chunk = spi_max_transfer_size(at25->spi); | 82 | size_t max_chunk = spi_max_transfer_size(at25->spi); |
| 83 | size_t num_msgs = DIV_ROUND_UP(count, max_chunk); | 83 | unsigned int msg_offset = offset; |
| 84 | size_t nr_bytes = 0; | 84 | size_t bytes_left = count; |
| 85 | unsigned int msg_offset; | 85 | size_t segment; |
| 86 | size_t msg_count; | ||
| 87 | u8 *cp; | 86 | u8 *cp; |
| 88 | ssize_t status; | 87 | ssize_t status; |
| 89 | struct spi_transfer t[2]; | 88 | struct spi_transfer t[2]; |
| @@ -97,9 +96,8 @@ static int at25_ee_read(void *priv, unsigned int offset, · 7 unmodified lines | |||
| 97 | if (unlikely(!count)) | 96 | if (unlikely(!count)) |
| 98 | return -EINVAL; | 97 | return -EINVAL; |
| 99 | 98 | ||
| 100 | msg_offset = (unsigned int)offset; | 99 | do { |
| 101 | msg_count = min(count, max_chunk); | 100 | segment = min(bytes_left, max_chunk); |
| 102 | while (num_msgs) { | ||
| 103 | cp = at25->command; | 101 | cp = at25->command; |
| 104 | 102 | ||
| 105 | instr = AT25_READ; | 103 | instr = AT25_READ; |
| @@ -131,8 +129,8 @@ static int at25_ee_read(void *priv, unsigned int offset, · 25 unmodified lines | |||
| 131 | t[0].len = at25->addrlen + 1; | 129 | t[0].len = at25->addrlen + 1; |
| 132 | spi_message_add_tail(&t[0], &m); | 130 | spi_message_add_tail(&t[0], &m); |
| 133 | 131 | ||
| 134 | t[1].rx_buf = buf + nr_bytes; | 132 | t[1].rx_buf = buf; |
| 135 | t[1].len = msg_count; | 133 | t[1].len = segment; |
| 136 | spi_message_add_tail(&t[1], &m); | 134 | spi_message_add_tail(&t[1], &m); |
| 137 | 135 | ||
| 138 | status = spi_sync(at25->spi, &m); | 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 | if (status) | 140 | if (status) |
| 143 | return status; | 141 | return status; |
| 144 | 142 | ||
| 145 | --num_msgs; | 143 | msg_offset += segment; |
| 146 | msg_offset += msg_count; | 144 | buf += segment; |
| 147 | nr_bytes += msg_count; | 145 | bytes_left -= segment; |
| 148 | } | 146 | } while (bytes_left > 0); |
| 149 | 147 | ||
| 150 | dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n", | 148 | dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n", |
| 151 | count, offset); | 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 | do { | 227 | do { |
| 230 | unsigned long timeout, retries; | 228 | unsigned long timeout, retries; |
| 231 | unsigned segment; | 229 | unsigned segment; |
| 232 | unsigned offset = (unsigned) off; | 230 | unsigned offset = off; |
| 233 | u8 *cp = bounce; | 231 | u8 *cp = bounce; |
| 234 | int sr; | 232 | int sr; |
| 235 | u8 instr; | 233 | u8 instr; |
| @@ -54,8 +54,6 @@ struct rtsx_ucr { · 53 unmodified lines | |||
| 54 | struct usb_device *pusb_dev; | 54 | struct usb_device *pusb_dev; |
| 55 | struct usb_interface *pusb_intf; | 55 | struct usb_interface *pusb_intf; |
| 56 | struct usb_sg_request current_sg; | 56 | struct usb_sg_request current_sg; |
| 57 | unsigned char *iobuf; | ||
| 58 | dma_addr_t iobuf_dma; | ||
| 59 | 57 | ||
| 60 | struct timer_list sg_timer; | 58 | struct timer_list sg_timer; |
| 61 | struct mutex dev_mutex; | 59 | struct mutex dev_mutex; |