summaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/Kconfig1
-rw-r--r--drivers/usb/storage/Makefile1
-rw-r--r--drivers/usb/storage/transport.c93
-rw-r--r--drivers/usb/storage/transport.h13
-rw-r--r--drivers/usb/storage/usb.c77
-rw-r--r--drivers/usb/storage/usb.h15
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>