diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/Kconfig | 1 | ||||
-rw-r--r-- | drivers/usb/storage/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 93 | ||||
-rw-r--r-- | drivers/usb/storage/transport.h | 13 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 77 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 15 |
6 files changed, 86 insertions, 114 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index b80c039117..efca9874d5 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only config USB_STORAGE tristate "USB Mass Storage support" select DISK diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index adf08433d5..8c60f3a2e5 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_USB_STORAGE) += usb-storage.o usb-storage-objs := usb.o transport.o diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 5186508ba6..be3b18dc66 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Most of this source has been derived from the Linux and * U-Boot USB Mass Storage driver implementations. * * Adapted for barebox: * Copyright (c) 2011, AMK Drives & Controls Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * */ #include <common.h> @@ -60,7 +49,7 @@ static int usb_stor_Bulk_clear_endpt_stall(struct us_data *us, unsigned int pipe /* Determine what the maximum LUN supported is */ int usb_stor_Bulk_max_lun(struct us_data *us) { - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; int len, ret = 0; unsigned char *iobuf = dma_alloc(1); @@ -96,40 +85,45 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev, void *data, u32 datalen) { struct us_data *us = usb_blkdev->us; - struct device_d *dev = &us->pusb_dev->dev; - struct bulk_cb_wrap cbw; - struct bulk_cs_wrap csw; + struct device *dev = &us->pusb_dev->dev; + struct bulk_cb_wrap *cbw; + struct bulk_cs_wrap *csw; int actlen, data_actlen; int result; unsigned int residue; unsigned int pipein = usb_rcvbulkpipe(us->pusb_dev, us->recv_bulk_ep); unsigned int pipeout = usb_sndbulkpipe(us->pusb_dev, us->send_bulk_ep); int dir_in = US_DIRECTION(cmd[0]); + int ret = 0; + + cbw = dma_alloc(sizeof(*cbw)); + csw = dma_alloc(sizeof(*csw)); /* set up the command wrapper */ - cbw.Signature = cpu_to_le32(US_BULK_CB_SIGN); - cbw.DataTransferLength = cpu_to_le32(datalen); - cbw.Flags = (dir_in ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT); - cbw.Tag = ++cbw_tag; - cbw.Lun = usb_blkdev->lun; - cbw.Length = cmdlen; + cbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); + cbw->DataTransferLength = cpu_to_le32(datalen); + cbw->Flags = (dir_in ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT); + cbw->Tag = ++cbw_tag; + cbw->Lun = usb_blkdev->lun; + cbw->Length = cmdlen; /* copy the command payload */ - memset(cbw.CDB, 0, sizeof(cbw.CDB)); - memcpy(cbw.CDB, cmd, cbw.Length); + memset(cbw->CDB, 0, sizeof(cbw->CDB)); + memcpy(cbw->CDB, cmd, cbw->Length); /* send it to out endpoint */ dev_dbg(dev, "Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n", - le32_to_cpu(cbw.Signature), cbw.Tag, - le32_to_cpu(cbw.DataTransferLength), cbw.Flags, - (cbw.Lun >> 4), (cbw.Lun & 0x0F), - cbw.Length); - result = usb_bulk_msg(us->pusb_dev, pipeout, &cbw, US_BULK_CB_WRAP_LEN, + le32_to_cpu(cbw->Signature), cbw->Tag, + le32_to_cpu(cbw->DataTransferLength), cbw->Flags, + (cbw->Lun >> 4), (cbw->Lun & 0x0F), + cbw->Length); + result = usb_bulk_msg(us->pusb_dev, pipeout, cbw, US_BULK_CB_WRAP_LEN, &actlen, USB_BULK_TO); dev_dbg(dev, "Bulk command transfer result=%d\n", result); if (result < 0) { usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_FAILED; + ret = USB_STOR_TRANSPORT_FAILED; + goto fail; } /* DATA STAGE */ @@ -152,13 +146,14 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev, if (result < 0) { dev_dbg(dev, "Device status: %lx\n", us->pusb_dev->status); usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_FAILED; + ret = USB_STOR_TRANSPORT_FAILED; + goto fail; } } /* STATUS phase + error handling */ dev_dbg(dev, "Attempting to get CSW...\n"); - result = usb_bulk_msg(us->pusb_dev, pipein, &csw, US_BULK_CS_WRAP_LEN, + result = usb_bulk_msg(us->pusb_dev, pipein, csw, US_BULK_CS_WRAP_LEN, &actlen, USB_BULK_TO); /* did the endpoint stall? */ @@ -169,7 +164,7 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev, if (result >= 0) { dev_dbg(dev, "Attempting to get CSW...\n"); result = usb_bulk_msg(us->pusb_dev, pipein, - &csw, US_BULK_CS_WRAP_LEN, + csw, US_BULK_CS_WRAP_LEN, &actlen, USB_BULK_TO); } } @@ -177,35 +172,39 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev, if (result < 0) { dev_dbg(dev, "Device status: %lx\n", us->pusb_dev->status); usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_FAILED; + ret = USB_STOR_TRANSPORT_FAILED; + goto fail; } /* check bulk status */ - residue = le32_to_cpu(csw.Residue); + residue = le32_to_cpu(csw->Residue); dev_dbg(dev, "Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", - le32_to_cpu(csw.Signature), csw.Tag, residue, csw.Status); - if (csw.Signature != cpu_to_le32(US_BULK_CS_SIGN)) { + le32_to_cpu(csw->Signature), csw->Tag, residue, csw->Status); + if (csw->Signature != cpu_to_le32(US_BULK_CS_SIGN)) { dev_dbg(dev, "Bad CSW signature\n"); usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_FAILED; - } else if (csw.Tag != cbw_tag) { + ret = USB_STOR_TRANSPORT_FAILED; + } else if (csw->Tag != cbw_tag) { dev_dbg(dev, "Mismatching tag\n"); usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_FAILED; - } else if (csw.Status >= US_BULK_STAT_PHASE) { + ret = USB_STOR_TRANSPORT_FAILED; + } else if (csw->Status >= US_BULK_STAT_PHASE) { dev_dbg(dev, "Status >= phase\n"); usb_stor_Bulk_reset(us); - return USB_STOR_TRANSPORT_ERROR; + ret = USB_STOR_TRANSPORT_ERROR; } else if (residue > datalen) { dev_dbg(dev, "residue (%uB) > req data (%uB)\n", residue, datalen); - return USB_STOR_TRANSPORT_FAILED; - } else if (csw.Status == US_BULK_STAT_FAIL) { + ret = USB_STOR_TRANSPORT_FAILED; + } else if (csw->Status == US_BULK_STAT_FAIL) { dev_dbg(dev, "FAILED\n"); - return USB_STOR_TRANSPORT_FAILED; + ret = USB_STOR_TRANSPORT_FAILED; } - return 0; +fail: + dma_free(cbw); + dma_free(csw); + return ret; } @@ -214,7 +213,7 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev, */ int usb_stor_Bulk_reset(struct us_data *us) { - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; int result; int result2; unsigned int pipe; diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 22d7dea3f5..5e08ae718a 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -1,21 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Most of this source has been derived from the Linux and * U-Boot USB Mass Storage driver implementations. * * Adapted for barebox: * Copyright (c) 2011, AMK Drives & Controls Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * */ #ifndef _TRANSPORT_H_ diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index a43b498e4b..cc241e69be 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -1,30 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Most of this source has been derived from the Linux and * U-Boot USB Mass Storage driver implementations. * * Adapted for barebox: * Copyright (c) 2011, AMK Drives & Controls Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * */ #include <common.h> #include <init.h> #include <malloc.h> +#include <dma.h> #include <errno.h> #include <scsi.h> -#include <usb/usb.h> -#include <usb/usb_defs.h> +#include <linux/usb/usb.h> +#include <linux/usb/usb_defs.h> #include <asm/unaligned.h> @@ -41,10 +31,10 @@ static int usb_stor_request_sense(struct us_blk_dev *usb_blkdev) { struct us_data *us = usb_blkdev->us; - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; u8 cmd[6]; const u8 datalen = 18; - u8 *data = xzalloc(datalen); + u8 *data = dma_alloc(datalen); dev_dbg(dev, "SCSI_REQ_SENSE\n"); @@ -55,7 +45,7 @@ static int usb_stor_request_sense(struct us_blk_dev *usb_blkdev) dev_dbg(dev, "Request Sense returned %02X %02X %02X\n", data[2], data[12], data[13]); - free(data); + dma_free(data); return 0; } @@ -84,7 +74,7 @@ static int usb_stor_transport(struct us_blk_dev *usb_blkdev, int retries, int request_sense_delay_ms) { struct us_data *us = usb_blkdev->us; - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; int i, ret; for (i = 0; i <= retries; i++) { @@ -111,11 +101,11 @@ static int usb_stor_transport(struct us_blk_dev *usb_blkdev, static int usb_stor_inquiry(struct us_blk_dev *usb_blkdev) { - struct device_d *dev = &usb_blkdev->us->pusb_dev->dev; + struct device *dev = &usb_blkdev->us->pusb_dev->dev; int ret; u8 cmd[6]; const u16 datalen = 36; - u8 *data = xzalloc(datalen); + u8 *data = dma_alloc(datalen); memset(cmd, 0, sizeof(cmd)); cmd[0] = SCSI_INQUIRY; @@ -137,7 +127,7 @@ static int usb_stor_inquiry(struct us_blk_dev *usb_blkdev) // TODO: process and store device info exit: - free(data); + dma_free(data); return ret; } @@ -162,10 +152,10 @@ static int usb_stor_test_unit_ready(struct us_blk_dev *usb_blkdev, u64 timeout_n static int read_capacity_16(struct us_blk_dev *usb_blkdev) { - struct device_d *dev = &usb_blkdev->us->pusb_dev->dev; + struct device *dev = &usb_blkdev->us->pusb_dev->dev; unsigned char cmd[16]; const u8 datalen = 32; - u8 *data = xzalloc(datalen); + u8 *data = dma_alloc(datalen); int ret; sector_t lba; unsigned sector_size; @@ -180,7 +170,7 @@ static int read_capacity_16(struct us_blk_dev *usb_blkdev) if (ret < 0) { dev_warn(dev, "Read Capacity(16) failed\n"); - return ret; + goto fail; } /* Note this is logical, not physical sector size */ @@ -192,21 +182,25 @@ static int read_capacity_16(struct us_blk_dev *usb_blkdev) if ((data[12] & 1) == 1) { dev_warn(dev, "Protection unsupported\n"); - return -ENOTSUPP; + ret = -ENOTSUPP; + goto fail; } usb_blkdev->blk.blockbits = SECTOR_SHIFT; usb_blkdev->blk.num_blocks = lba + 1; - return sector_size; + ret = sector_size; +fail: + dma_free(data); + return ret; } static int read_capacity_10(struct us_blk_dev *usb_blkdev) { - struct device_d *dev = &usb_blkdev->us->pusb_dev->dev; + struct device *dev = &usb_blkdev->us->pusb_dev->dev; unsigned char cmd[16]; const u32 datalen = 8; - __be32 *data = xzalloc(datalen); + __be32 *data = dma_alloc(datalen); int ret; sector_t lba; unsigned sector_size; @@ -219,7 +213,7 @@ static int read_capacity_10(struct us_blk_dev *usb_blkdev) if (ret < 0) { dev_warn(dev, "Read Capacity(10) failed\n"); - return ret; + goto fail; } sector_size = be32_to_cpu(data[1]); @@ -234,7 +228,10 @@ static int read_capacity_10(struct us_blk_dev *usb_blkdev) usb_blkdev->blk.num_blocks = lba + 1; usb_blkdev->blk.blockbits = SECTOR_SHIFT; - return SECTOR_SIZE; + ret = SECTOR_SIZE; +fail: + dma_free(data); + return ret; } static int usb_stor_io_16(struct us_blk_dev *usb_blkdev, u8 opcode, @@ -280,7 +277,7 @@ static int usb_stor_blk_io(struct block_device *disk_dev, struct us_blk_dev, blk); struct us_data *us = pblk_dev->us; - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; int result; /* ensure unit ready */ @@ -353,7 +350,7 @@ static struct block_device_ops usb_mass_storage_ops = { static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev) { struct us_data *us = pblk_dev->us; - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; int result; /* get device info */ @@ -399,7 +396,7 @@ static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev) /* Create and register a disk device for the specified LUN */ static int usb_stor_add_blkdev(struct us_data *us, unsigned char lun) { - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; struct us_blk_dev *pblk_dev; int result; @@ -424,6 +421,7 @@ static int usb_stor_add_blkdev(struct us_data *us, unsigned char lun) pblk_dev->blk.cdev.name = basprintf("disk%d", result); pblk_dev->blk.blockbits = SECTOR_SHIFT; + pblk_dev->blk.type = BLK_TYPE_USB; result = blockdevice_register(&pblk_dev->blk); if (result != 0) { @@ -431,11 +429,6 @@ static int usb_stor_add_blkdev(struct us_data *us, unsigned char lun) goto BadDevice; } - /* create partitions on demand */ - result = parse_partition_table(&pblk_dev->blk); - if (result != 0) - dev_warn(dev, "No partition table found\n"); - list_add_tail(&pblk_dev->list, &us->blk_dev_list); dev_dbg(dev, "USB disk device successfully added\n"); @@ -454,7 +447,7 @@ BadDevice: /* Get the transport settings */ static void get_transport(struct us_data *us) { - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; switch (us->protocol) { case US_PR_BULK: us->transport_name = "Bulk"; @@ -469,7 +462,7 @@ static void get_transport(struct us_data *us) /* Get the endpoint settings */ static int get_pipes(struct us_data *us, struct usb_interface *intf) { - struct device_d *dev = &us->pusb_dev->dev; + struct device *dev = &us->pusb_dev->dev; unsigned int i; struct usb_endpoint_descriptor *ep; struct usb_endpoint_descriptor *ep_in = NULL; @@ -510,7 +503,7 @@ static int get_pipes(struct us_data *us, struct usb_interface *intf) /* Scan device's LUNs, registering a disk device for each LUN */ static int usb_stor_scan(struct usb_device *usbdev, struct us_data *us) { - struct device_d *dev = &usbdev->dev; + struct device *dev = &usbdev->dev; unsigned char lun; int num_devs = 0; @@ -534,7 +527,7 @@ static int usb_stor_scan(struct usb_device *usbdev, struct us_data *us) static int usb_stor_probe(struct usb_device *usbdev, const struct usb_device_id *id) { - struct device_d *dev = &usbdev->dev; + struct device *dev = &usbdev->dev; struct us_data *us; int result; int ifno; diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index cd4904f03b..ae16d7b60b 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -1,27 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Most of this source has been derived from the Linux and * U-Boot USB Mass Storage driver implementations. * * Adapted for barebox: * Copyright (c) 2011, AMK Drives & Controls Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * */ #ifndef _STORAGE_USB_H_ #define _STORAGE_USB_H_ -#include <usb/usb.h> +#include <linux/usb/usb.h> #include <block.h> #include <disks.h> #include <scsi.h> |