diff options
author | David Mosberger-Tang <davidm@egauge.net> | 2014-05-29 00:40:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-29 14:19:30 -0400 |
commit | 05dfa5c9bc37933181b619e42ec0eeb41ef31362 (patch) | |
tree | ebfb9688445978d2e69b9638d0308dd7692fd320 /drivers/usb | |
parent | 00c5aa178a5ba217a4143f8a5f70630550a87600 (diff) |
usb: host: max3421-hcd: fix "spi_rd8" uses dynamic stack allocation warning
kmalloc the SPI rx and tx data buffers. This appears to be the only
portable way to guarantee that the buffers are DMA-safe (e.g., in
separate DMA cache-lines). This patch makes the spi_rdX()/spi_wrX()
non-reentrant, but that's OK because calls to them are guaranteed to
be serialized by the per-HCD SPI-thread.
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: David Mosberger <davidm@egauge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/max3421-hcd.c | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 714f99faa14a..ccb1bc42b4d2 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c | |||
@@ -102,6 +102,10 @@ enum scheduling_pass { | |||
102 | SCHED_PASS_DONE | 102 | SCHED_PASS_DONE |
103 | }; | 103 | }; |
104 | 104 | ||
105 | struct max3421_dma_buf { | ||
106 | u8 data[2]; | ||
107 | }; | ||
108 | |||
105 | struct max3421_hcd { | 109 | struct max3421_hcd { |
106 | spinlock_t lock; | 110 | spinlock_t lock; |
107 | 111 | ||
@@ -124,6 +128,12 @@ struct max3421_hcd { | |||
124 | u8 rev; /* chip revision */ | 128 | u8 rev; /* chip revision */ |
125 | u16 frame_number; | 129 | u16 frame_number; |
126 | /* | 130 | /* |
131 | * kmalloc'd buffers guaranteed to be in separate (DMA) | ||
132 | * cache-lines: | ||
133 | */ | ||
134 | struct max3421_dma_buf *tx; | ||
135 | struct max3421_dma_buf *rx; | ||
136 | /* | ||
127 | * URB we're currently processing. Must not be reset to NULL | 137 | * URB we're currently processing. Must not be reset to NULL |
128 | * unless MAX3421E chip is idle: | 138 | * unless MAX3421E chip is idle: |
129 | */ | 139 | */ |
@@ -332,51 +342,47 @@ max3421_to_hcd(struct max3421_hcd *max3421_hcd) | |||
332 | static u8 | 342 | static u8 |
333 | spi_rd8(struct usb_hcd *hcd, unsigned int reg) | 343 | spi_rd8(struct usb_hcd *hcd, unsigned int reg) |
334 | { | 344 | { |
345 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | ||
335 | struct spi_device *spi = to_spi_device(hcd->self.controller); | 346 | struct spi_device *spi = to_spi_device(hcd->self.controller); |
336 | struct spi_transfer transfer; | 347 | struct spi_transfer transfer; |
337 | u8 tx_data[1]; | ||
338 | /* | ||
339 | * RX data must be in its own cache-line so it stays flushed | ||
340 | * from the cache until the transfer is complete. Otherwise, | ||
341 | * we get stale data from the cache. | ||
342 | */ | ||
343 | u8 rx_data[SMP_CACHE_BYTES] ____cacheline_aligned; | ||
344 | struct spi_message msg; | 348 | struct spi_message msg; |
345 | 349 | ||
346 | memset(&transfer, 0, sizeof(transfer)); | 350 | memset(&transfer, 0, sizeof(transfer)); |
347 | 351 | ||
348 | spi_message_init(&msg); | 352 | spi_message_init(&msg); |
349 | 353 | ||
350 | tx_data[0] = (field(reg, MAX3421_SPI_REG_SHIFT) | | 354 | max3421_hcd->tx->data[0] = |
351 | field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); | 355 | (field(reg, MAX3421_SPI_REG_SHIFT) | |
356 | field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); | ||
352 | 357 | ||
353 | transfer.tx_buf = tx_data; | 358 | transfer.tx_buf = max3421_hcd->tx->data; |
354 | transfer.rx_buf = rx_data; | 359 | transfer.rx_buf = max3421_hcd->rx->data; |
355 | transfer.len = 2; | 360 | transfer.len = 2; |
356 | 361 | ||
357 | spi_message_add_tail(&transfer, &msg); | 362 | spi_message_add_tail(&transfer, &msg); |
358 | spi_sync(spi, &msg); | 363 | spi_sync(spi, &msg); |
359 | 364 | ||
360 | return rx_data[1]; | 365 | return max3421_hcd->rx->data[1]; |
361 | } | 366 | } |
362 | 367 | ||
363 | static void | 368 | static void |
364 | spi_wr8(struct usb_hcd *hcd, unsigned int reg, u8 val) | 369 | spi_wr8(struct usb_hcd *hcd, unsigned int reg, u8 val) |
365 | { | 370 | { |
366 | struct spi_device *spi = to_spi_device(hcd->self.controller); | 371 | struct spi_device *spi = to_spi_device(hcd->self.controller); |
372 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | ||
367 | struct spi_transfer transfer; | 373 | struct spi_transfer transfer; |
368 | struct spi_message msg; | 374 | struct spi_message msg; |
369 | u8 tx_data[2]; | ||
370 | 375 | ||
371 | memset(&transfer, 0, sizeof(transfer)); | 376 | memset(&transfer, 0, sizeof(transfer)); |
372 | 377 | ||
373 | spi_message_init(&msg); | 378 | spi_message_init(&msg); |
374 | 379 | ||
375 | tx_data[0] = (field(reg, MAX3421_SPI_REG_SHIFT) | | 380 | max3421_hcd->tx->data[0] = |
376 | field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); | 381 | (field(reg, MAX3421_SPI_REG_SHIFT) | |
377 | tx_data[1] = val; | 382 | field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); |
383 | max3421_hcd->tx->data[1] = val; | ||
378 | 384 | ||
379 | transfer.tx_buf = tx_data; | 385 | transfer.tx_buf = max3421_hcd->tx->data; |
380 | transfer.len = 2; | 386 | transfer.len = 2; |
381 | 387 | ||
382 | spi_message_add_tail(&transfer, &msg); | 388 | spi_message_add_tail(&transfer, &msg); |
@@ -387,18 +393,18 @@ static void | |||
387 | spi_rd_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) | 393 | spi_rd_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) |
388 | { | 394 | { |
389 | struct spi_device *spi = to_spi_device(hcd->self.controller); | 395 | struct spi_device *spi = to_spi_device(hcd->self.controller); |
396 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | ||
390 | struct spi_transfer transfer[2]; | 397 | struct spi_transfer transfer[2]; |
391 | struct spi_message msg; | 398 | struct spi_message msg; |
392 | u8 cmd; | ||
393 | 399 | ||
394 | memset(transfer, 0, sizeof(transfer)); | 400 | memset(transfer, 0, sizeof(transfer)); |
395 | 401 | ||
396 | spi_message_init(&msg); | 402 | spi_message_init(&msg); |
397 | 403 | ||
398 | cmd = (field(reg, MAX3421_SPI_REG_SHIFT) | | 404 | max3421_hcd->tx->data[0] = |
399 | field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); | 405 | (field(reg, MAX3421_SPI_REG_SHIFT) | |
400 | 406 | field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); | |
401 | transfer[0].tx_buf = &cmd; | 407 | transfer[0].tx_buf = max3421_hcd->tx->data; |
402 | transfer[0].len = 1; | 408 | transfer[0].len = 1; |
403 | 409 | ||
404 | transfer[1].rx_buf = buf; | 410 | transfer[1].rx_buf = buf; |
@@ -413,18 +419,19 @@ static void | |||
413 | spi_wr_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) | 419 | spi_wr_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) |
414 | { | 420 | { |
415 | struct spi_device *spi = to_spi_device(hcd->self.controller); | 421 | struct spi_device *spi = to_spi_device(hcd->self.controller); |
422 | struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); | ||
416 | struct spi_transfer transfer[2]; | 423 | struct spi_transfer transfer[2]; |
417 | struct spi_message msg; | 424 | struct spi_message msg; |
418 | u8 cmd; | ||
419 | 425 | ||
420 | memset(transfer, 0, sizeof(transfer)); | 426 | memset(transfer, 0, sizeof(transfer)); |
421 | 427 | ||
422 | spi_message_init(&msg); | 428 | spi_message_init(&msg); |
423 | 429 | ||
424 | cmd = (field(reg, MAX3421_SPI_REG_SHIFT) | | 430 | max3421_hcd->tx->data[0] = |
425 | field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); | 431 | (field(reg, MAX3421_SPI_REG_SHIFT) | |
432 | field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); | ||
426 | 433 | ||
427 | transfer[0].tx_buf = &cmd; | 434 | transfer[0].tx_buf = max3421_hcd->tx->data; |
428 | transfer[0].len = 1; | 435 | transfer[0].len = 1; |
429 | 436 | ||
430 | transfer[1].tx_buf = buf; | 437 | transfer[1].tx_buf = buf; |
@@ -1834,8 +1841,8 @@ static int | |||
1834 | max3421_probe(struct spi_device *spi) | 1841 | max3421_probe(struct spi_device *spi) |
1835 | { | 1842 | { |
1836 | struct max3421_hcd *max3421_hcd; | 1843 | struct max3421_hcd *max3421_hcd; |
1837 | struct usb_hcd *hcd; | 1844 | struct usb_hcd *hcd = NULL; |
1838 | int retval; | 1845 | int retval = -ENOMEM; |
1839 | 1846 | ||
1840 | if (spi_setup(spi) < 0) { | 1847 | if (spi_setup(spi) < 0) { |
1841 | dev_err(&spi->dev, "Unable to setup SPI bus"); | 1848 | dev_err(&spi->dev, "Unable to setup SPI bus"); |
@@ -1846,7 +1853,7 @@ max3421_probe(struct spi_device *spi) | |||
1846 | dev_name(&spi->dev)); | 1853 | dev_name(&spi->dev)); |
1847 | if (!hcd) { | 1854 | if (!hcd) { |
1848 | dev_err(&spi->dev, "failed to create HCD structure\n"); | 1855 | dev_err(&spi->dev, "failed to create HCD structure\n"); |
1849 | return -ENOMEM; | 1856 | goto error; |
1850 | } | 1857 | } |
1851 | set_bit(HCD_FLAG_POLL_RH, &hcd->flags); | 1858 | set_bit(HCD_FLAG_POLL_RH, &hcd->flags); |
1852 | max3421_hcd = hcd_to_max3421(hcd); | 1859 | max3421_hcd = hcd_to_max3421(hcd); |
@@ -1854,29 +1861,48 @@ max3421_probe(struct spi_device *spi) | |||
1854 | max3421_hcd_list = max3421_hcd; | 1861 | max3421_hcd_list = max3421_hcd; |
1855 | INIT_LIST_HEAD(&max3421_hcd->ep_list); | 1862 | INIT_LIST_HEAD(&max3421_hcd->ep_list); |
1856 | 1863 | ||
1864 | max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); | ||
1865 | if (!max3421_hcd->tx) { | ||
1866 | dev_err(&spi->dev, "failed to kmalloc tx buffer\n"); | ||
1867 | goto error; | ||
1868 | } | ||
1869 | max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); | ||
1870 | if (!max3421_hcd->rx) { | ||
1871 | dev_err(&spi->dev, "failed to kmalloc rx buffer\n"); | ||
1872 | goto error; | ||
1873 | } | ||
1874 | |||
1857 | max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, | 1875 | max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, |
1858 | "max3421_spi_thread"); | 1876 | "max3421_spi_thread"); |
1859 | if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) { | 1877 | if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) { |
1860 | dev_err(&spi->dev, | 1878 | dev_err(&spi->dev, |
1861 | "failed to create SPI thread (out of memory)\n"); | 1879 | "failed to create SPI thread (out of memory)\n"); |
1862 | return -ENOMEM; | 1880 | goto error; |
1863 | } | 1881 | } |
1864 | 1882 | ||
1865 | retval = usb_add_hcd(hcd, 0, 0); | 1883 | retval = usb_add_hcd(hcd, 0, 0); |
1866 | if (retval) { | 1884 | if (retval) { |
1867 | dev_err(&spi->dev, "failed to add HCD\n"); | 1885 | dev_err(&spi->dev, "failed to add HCD\n"); |
1868 | usb_put_hcd(hcd); | 1886 | goto error; |
1869 | return retval; | ||
1870 | } | 1887 | } |
1871 | 1888 | ||
1872 | retval = request_irq(spi->irq, max3421_irq_handler, | 1889 | retval = request_irq(spi->irq, max3421_irq_handler, |
1873 | IRQF_TRIGGER_LOW, "max3421", hcd); | 1890 | IRQF_TRIGGER_LOW, "max3421", hcd); |
1874 | if (retval < 0) { | 1891 | if (retval < 0) { |
1875 | usb_put_hcd(hcd); | ||
1876 | dev_err(&spi->dev, "failed to request irq %d\n", spi->irq); | 1892 | dev_err(&spi->dev, "failed to request irq %d\n", spi->irq); |
1877 | return retval; | 1893 | goto error; |
1878 | } | 1894 | } |
1879 | return 0; | 1895 | return 0; |
1896 | |||
1897 | error: | ||
1898 | if (hcd) { | ||
1899 | kfree(max3421_hcd->tx); | ||
1900 | kfree(max3421_hcd->rx); | ||
1901 | if (max3421_hcd->spi_thread) | ||
1902 | kthread_stop(max3421_hcd->spi_thread); | ||
1903 | usb_put_hcd(hcd); | ||
1904 | } | ||
1905 | return retval; | ||
1880 | } | 1906 | } |
1881 | 1907 | ||
1882 | static int | 1908 | static int |