All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@linaro.org>
To: Sunny Luo <sunny.luo@amlogic.com>
Cc: linux-amlogic@lists.infradead.org, linux-spi@vger.kernel.org
Subject: [bug report] spi: Add Amlogic SPISG driver
Date: Mon, 4 Aug 2025 11:14:00 +0300	[thread overview]
Message-ID: <aJBryDMreHB9dI_i@stanley.mountain> (raw)

Hello Sunny Luo,

Commit cef9991e04ae ("spi: Add Amlogic SPISG driver") from Jul 18,
2025 (linux-next), leads to the following Smatch static checker
warning:

	drivers/spi/spi-amlogic-spisg.c:314 aml_spisg_setup_transfer()
	error: we previously assumed 'exdesc' could be null (see line 261)

drivers/spi/spi-amlogic-spisg.c
    248 static int aml_spisg_setup_transfer(struct spisg_device *spisg,
    249                                     struct spi_transfer *xfer,
    250                                     struct spisg_descriptor *desc,
    251                                     struct spisg_descriptor_extra *exdesc)
    252 {
    253         int block_size, blocks;
    254         struct device *dev = &spisg->pdev->dev;
    255         struct spisg_sg_link *ccsg;
    256         int ccsg_len;
    257         dma_addr_t paddr;
    258         int ret;
    259 
    260         memset(desc, 0, sizeof(*desc));
    261         if (exdesc)
                    ^^^^^^
Checked for NULL

    262                 memset(exdesc, 0, sizeof(*exdesc));
    263         aml_spisg_set_speed(spisg, xfer->speed_hz);
    264         xfer->effective_speed_hz = spisg->effective_speed_hz;
    265 
    266         desc->cfg_start = spisg->cfg_start;
    267         desc->cfg_bus = spisg->cfg_bus;
    268 
    269         block_size = xfer->bits_per_word >> 3;
    270         blocks = xfer->len / block_size;
    271 
    272         desc->cfg_start |= FIELD_PREP(CFG_EOC, 0);
    273         desc->cfg_bus |= FIELD_PREP(CFG_KEEP_SS, !xfer->cs_change);
    274         desc->cfg_bus |= FIELD_PREP(CFG_NULL_CTL, 0);
    275 
    276         if (xfer->tx_buf || xfer->tx_dma) {
    277                 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->tx_nbits]);
    278                 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_WRITE);
    279         }
    280         if (xfer->rx_buf || xfer->rx_dma) {
    281                 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->rx_nbits]);
    282                 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_READ);
    283         }
    284 
    285         if (FIELD_GET(CFG_OP_MODE, desc->cfg_start) == SPISG_OP_MODE_READ_STS) {
    286                 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, blocks) |
    287                                    FIELD_PREP(CFG_BLOCK_NUM, 1);
    288         } else {
    289                 blocks = min_t(int, blocks, SPISG_BLOCK_MAX);
    290                 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, block_size & 0x7) |
    291                                    FIELD_PREP(CFG_BLOCK_NUM, blocks);
    292         }
    293 
    294         if (xfer->tx_sg.nents && xfer->tx_sg.sgl) {
    295                 ccsg_len = xfer->tx_sg.nents * sizeof(struct spisg_sg_link);
    296                 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
    297                 if (!ccsg) {
    298                         dev_err(dev, "alloc tx_ccsg failed\n");
    299                         return -ENOMEM;
    300                 }
    301 
    302                 aml_spisg_sg_xlate(&xfer->tx_sg, ccsg);
    303                 paddr = dma_map_single(dev, (void *)ccsg,
    304                                        ccsg_len, DMA_TO_DEVICE);
    305                 ret = dma_mapping_error(dev, paddr);
    306                 if (ret) {
    307                         kfree(ccsg);
    308                         dev_err(dev, "tx ccsg map failed\n");
    309                         return ret;
    310                 }
    311 
    312                 desc->tx_paddr = paddr;
    313                 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_SG);
--> 314                 exdesc->tx_ccsg = ccsg;
                        ^^^^^^^^
Unchecked dereference

    315                 exdesc->tx_ccsg_len = ccsg_len;
    316                 dma_sync_sgtable_for_device(spisg->controller->cur_tx_dma_dev,
    317                                             &xfer->tx_sg, DMA_TO_DEVICE);
    318         } else if (xfer->tx_buf || xfer->tx_dma) {
    319                 paddr = xfer->tx_dma;
    320                 if (!paddr) {
    321                         paddr = dma_map_single(dev, (void *)xfer->tx_buf,
    322                                                xfer->len, DMA_TO_DEVICE);
    323                         ret = dma_mapping_error(dev, paddr);
    324                         if (ret) {
    325                                 dev_err(dev, "tx buf map failed\n");
    326                                 return ret;
    327                         }
    328                 }
    329                 desc->tx_paddr = paddr;
    330                 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_MEM);
    331         }
    332 
    333         if (xfer->rx_sg.nents && xfer->rx_sg.sgl) {
    334                 ccsg_len = xfer->rx_sg.nents * sizeof(struct spisg_sg_link);
    335                 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
    336                 if (!ccsg) {
    337                         dev_err(dev, "alloc rx_ccsg failed\n");
    338                         return -ENOMEM;
    339                 }
    340 
    341                 aml_spisg_sg_xlate(&xfer->rx_sg, ccsg);
    342                 paddr = dma_map_single(dev, (void *)ccsg,
    343                                        ccsg_len, DMA_TO_DEVICE);
    344                 ret = dma_mapping_error(dev, paddr);
    345                 if (ret) {
    346                         kfree(ccsg);
    347                         dev_err(dev, "rx ccsg map failed\n");
    348                         return ret;
    349                 }
    350 
    351                 desc->rx_paddr = paddr;
    352                 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_SG);
    353                 exdesc->rx_ccsg = ccsg;
    354                 exdesc->rx_ccsg_len = ccsg_len;
    355                 dma_sync_sgtable_for_device(spisg->controller->cur_rx_dma_dev,
    356                                             &xfer->rx_sg, DMA_FROM_DEVICE);
    357         } else if (xfer->rx_buf || xfer->rx_dma) {
    358                 paddr = xfer->rx_dma;
    359                 if (!paddr) {
    360                         paddr = dma_map_single(dev, xfer->rx_buf,
    361                                                xfer->len, DMA_FROM_DEVICE);
    362                         ret = dma_mapping_error(dev, paddr);
    363                         if (ret) {
    364                                 dev_err(dev, "rx buf map failed\n");
    365                                 return ret;
    366                         }
    367                 }
    368 
    369                 desc->rx_paddr = paddr;
    370                 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_MEM);
    371         }
    372 
    373         return 0;
    374 }

regards,
dan carpenter

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

WARNING: multiple messages have this Message-ID (diff)
From: Dan Carpenter <dan.carpenter@linaro.org>
To: Sunny Luo <sunny.luo@amlogic.com>
Cc: linux-amlogic@lists.infradead.org, linux-spi@vger.kernel.org
Subject: [bug report] spi: Add Amlogic SPISG driver
Date: Mon, 4 Aug 2025 11:14:00 +0300	[thread overview]
Message-ID: <aJBryDMreHB9dI_i@stanley.mountain> (raw)

Hello Sunny Luo,

Commit cef9991e04ae ("spi: Add Amlogic SPISG driver") from Jul 18,
2025 (linux-next), leads to the following Smatch static checker
warning:

	drivers/spi/spi-amlogic-spisg.c:314 aml_spisg_setup_transfer()
	error: we previously assumed 'exdesc' could be null (see line 261)

drivers/spi/spi-amlogic-spisg.c
    248 static int aml_spisg_setup_transfer(struct spisg_device *spisg,
    249                                     struct spi_transfer *xfer,
    250                                     struct spisg_descriptor *desc,
    251                                     struct spisg_descriptor_extra *exdesc)
    252 {
    253         int block_size, blocks;
    254         struct device *dev = &spisg->pdev->dev;
    255         struct spisg_sg_link *ccsg;
    256         int ccsg_len;
    257         dma_addr_t paddr;
    258         int ret;
    259 
    260         memset(desc, 0, sizeof(*desc));
    261         if (exdesc)
                    ^^^^^^
Checked for NULL

    262                 memset(exdesc, 0, sizeof(*exdesc));
    263         aml_spisg_set_speed(spisg, xfer->speed_hz);
    264         xfer->effective_speed_hz = spisg->effective_speed_hz;
    265 
    266         desc->cfg_start = spisg->cfg_start;
    267         desc->cfg_bus = spisg->cfg_bus;
    268 
    269         block_size = xfer->bits_per_word >> 3;
    270         blocks = xfer->len / block_size;
    271 
    272         desc->cfg_start |= FIELD_PREP(CFG_EOC, 0);
    273         desc->cfg_bus |= FIELD_PREP(CFG_KEEP_SS, !xfer->cs_change);
    274         desc->cfg_bus |= FIELD_PREP(CFG_NULL_CTL, 0);
    275 
    276         if (xfer->tx_buf || xfer->tx_dma) {
    277                 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->tx_nbits]);
    278                 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_WRITE);
    279         }
    280         if (xfer->rx_buf || xfer->rx_dma) {
    281                 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->rx_nbits]);
    282                 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_READ);
    283         }
    284 
    285         if (FIELD_GET(CFG_OP_MODE, desc->cfg_start) == SPISG_OP_MODE_READ_STS) {
    286                 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, blocks) |
    287                                    FIELD_PREP(CFG_BLOCK_NUM, 1);
    288         } else {
    289                 blocks = min_t(int, blocks, SPISG_BLOCK_MAX);
    290                 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, block_size & 0x7) |
    291                                    FIELD_PREP(CFG_BLOCK_NUM, blocks);
    292         }
    293 
    294         if (xfer->tx_sg.nents && xfer->tx_sg.sgl) {
    295                 ccsg_len = xfer->tx_sg.nents * sizeof(struct spisg_sg_link);
    296                 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
    297                 if (!ccsg) {
    298                         dev_err(dev, "alloc tx_ccsg failed\n");
    299                         return -ENOMEM;
    300                 }
    301 
    302                 aml_spisg_sg_xlate(&xfer->tx_sg, ccsg);
    303                 paddr = dma_map_single(dev, (void *)ccsg,
    304                                        ccsg_len, DMA_TO_DEVICE);
    305                 ret = dma_mapping_error(dev, paddr);
    306                 if (ret) {
    307                         kfree(ccsg);
    308                         dev_err(dev, "tx ccsg map failed\n");
    309                         return ret;
    310                 }
    311 
    312                 desc->tx_paddr = paddr;
    313                 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_SG);
--> 314                 exdesc->tx_ccsg = ccsg;
                        ^^^^^^^^
Unchecked dereference

    315                 exdesc->tx_ccsg_len = ccsg_len;
    316                 dma_sync_sgtable_for_device(spisg->controller->cur_tx_dma_dev,
    317                                             &xfer->tx_sg, DMA_TO_DEVICE);
    318         } else if (xfer->tx_buf || xfer->tx_dma) {
    319                 paddr = xfer->tx_dma;
    320                 if (!paddr) {
    321                         paddr = dma_map_single(dev, (void *)xfer->tx_buf,
    322                                                xfer->len, DMA_TO_DEVICE);
    323                         ret = dma_mapping_error(dev, paddr);
    324                         if (ret) {
    325                                 dev_err(dev, "tx buf map failed\n");
    326                                 return ret;
    327                         }
    328                 }
    329                 desc->tx_paddr = paddr;
    330                 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_MEM);
    331         }
    332 
    333         if (xfer->rx_sg.nents && xfer->rx_sg.sgl) {
    334                 ccsg_len = xfer->rx_sg.nents * sizeof(struct spisg_sg_link);
    335                 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
    336                 if (!ccsg) {
    337                         dev_err(dev, "alloc rx_ccsg failed\n");
    338                         return -ENOMEM;
    339                 }
    340 
    341                 aml_spisg_sg_xlate(&xfer->rx_sg, ccsg);
    342                 paddr = dma_map_single(dev, (void *)ccsg,
    343                                        ccsg_len, DMA_TO_DEVICE);
    344                 ret = dma_mapping_error(dev, paddr);
    345                 if (ret) {
    346                         kfree(ccsg);
    347                         dev_err(dev, "rx ccsg map failed\n");
    348                         return ret;
    349                 }
    350 
    351                 desc->rx_paddr = paddr;
    352                 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_SG);
    353                 exdesc->rx_ccsg = ccsg;
    354                 exdesc->rx_ccsg_len = ccsg_len;
    355                 dma_sync_sgtable_for_device(spisg->controller->cur_rx_dma_dev,
    356                                             &xfer->rx_sg, DMA_FROM_DEVICE);
    357         } else if (xfer->rx_buf || xfer->rx_dma) {
    358                 paddr = xfer->rx_dma;
    359                 if (!paddr) {
    360                         paddr = dma_map_single(dev, xfer->rx_buf,
    361                                                xfer->len, DMA_FROM_DEVICE);
    362                         ret = dma_mapping_error(dev, paddr);
    363                         if (ret) {
    364                                 dev_err(dev, "rx buf map failed\n");
    365                                 return ret;
    366                         }
    367                 }
    368 
    369                 desc->rx_paddr = paddr;
    370                 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_MEM);
    371         }
    372 
    373         return 0;
    374 }

regards,
dan carpenter

             reply	other threads:[~2025-08-04  8:41 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-04  8:14 Dan Carpenter [this message]
2025-08-04  8:14 ` [bug report] spi: Add Amlogic SPISG driver Dan Carpenter
  -- strict thread matches above, loose matches on Subject: below --
2025-08-01 13:04 Dan Carpenter
2025-08-01 13:04 ` Dan Carpenter
2025-08-01 13:02 Dan Carpenter
2025-08-01 13:02 ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aJBryDMreHB9dI_i@stanley.mountain \
    --to=dan.carpenter@linaro.org \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=sunny.luo@amlogic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.