[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cdi-devel] [PATCH] No STALL
From: Max Reitz <max@xxxxxxxxxx>
* Stall problem removed, hopefully more correct
msc driver code.
Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
usb/include/usb.h | 19 +++---
usb/main.c | 3 +
usb/msd.c | 180 +++++++++++++++++++++++++----------------------------
3 files changed, 98 insertions(+), 104 deletions(-)
diff --git a/usb/include/usb.h b/usb/include/usb.h
index b6ff391..584f31f 100644
--- a/usb/include/usb.h
+++ b/usb/include/usb.h
@@ -93,15 +93,16 @@ enum usb_packet_type {
#define DESC_OTHER_SPEED_CONFIGURATION 7
#define DESC_INTERFACE_POWER 8
-#define USB_NO_ERROR 0x00
-#define USB_STALLED 0x01
-#define USB_BUFFER_ERROR 0x02
-#define USB_BABBLE 0x04
-#define USB_NAK 0x08
-#define USB_CRC 0x10
-#define USB_TIMEOUT 0x20
-#define USB_BITSTUFF 0x40
-#define USB_TRIVIAL_ERROR 0x80
+#define USB_NO_ERROR 0x0000
+#define USB_STALLED 0x0001
+#define USB_BUFFER_ERROR 0x0002
+#define USB_BABBLE 0x0004
+#define USB_NAK 0x0008
+#define USB_CRC 0x0010
+#define USB_TIMEOUT 0x0020
+#define USB_BITSTUFF 0x0040
+#define USB_TRIVIAL_ERROR 0x0080
+#define USB_STATUS_ERROR 0x0100
#define USB_TOD_SETUP 0x0001
#define USB_TOD_SETUP_DATA_IN 0x0002
diff --git a/usb/main.c b/usb/main.c
index 878aefe..9eb20d8 100644
--- a/usb/main.c
+++ b/usb/main.c
@@ -126,6 +126,9 @@ int usb_do_packet(struct usb_device* device, struct usb_packet* packet)
}
while (error == USB_NAK) {
error = device->hci->do_packet(device, packet);
+ if (error == USB_NAK) {
+ cdi_sleep_ms(5);
+ }
}
if (error == USB_STALLED) {
printf("[usb] ENDPOINT %i DES GERÃ?TS %i STALLED!\n", packet->endpoint,
diff --git a/usb/msd.c b/usb/msd.c
index ad6f362..471856a 100644
--- a/usb/msd.c
+++ b/usb/msd.c
@@ -169,13 +169,15 @@ void register_msd(struct usb_device* usbdev)
for (i = 0; i < usbdev->interface->num_endpoints; i++) {
ep_desc = address;
if ((ep_desc->endpoint_address & 0x80) &&
- (ep_desc->attributes == 0x02) && (msc->bulk_ep_in == NULL)) //BULK-IN
+ (ep_desc->attributes == 0x02) && (msc->bulk_ep_in == NULL))
{
+ //BULK-IN
msc->bulk_ep_in = ep_desc;
} else if (!(ep_desc->endpoint_address & 0x80) &&
(ep_desc->attributes == 0x02) &&
- (msc->bulk_ep_out == NULL)) //BULK-OUT
+ (msc->bulk_ep_out == NULL))
{
+ //BULK-OUT
msc->bulk_ep_out = ep_desc;
}
address += sizeof(struct endpoint_desc);
@@ -252,7 +254,7 @@ static int read_status(struct usb_device* usbdev, uint32_t expected_tag)
struct command_status_wrapper* csw;
int error;
- if (cdi_alloc_phys_mem(sizeof(struct command_status_wrapper), (void**) &csw,
+ if (cdi_alloc_phys_mem(sizeof(*csw), (void**) &csw,
(void**) &pcsw) == -1)
{
return USB_TRIVIAL_ERROR;
@@ -274,9 +276,11 @@ static int read_status(struct usb_device* usbdev, uint32_t expected_tag)
if ((csw->csw_signature != CSW_SIGNATURE) ||
(csw->csw_tag != expected_tag) || csw->csw_status)
{
- return USB_CRC; //Watt weiÃ? denn ich
-
+ dprintf("0x%08X %i==%i 0x%08X\n", csw->csw_signature, csw->csw_tag,
+ expected_tag, csw->csw_status);
+ return USB_STATUS_ERROR;
}
+
return USB_NO_ERROR;
}
@@ -358,9 +362,9 @@ static int msd_ready(struct usb_device* usbdev)
cbw->cbw_signature = CBW_SIGNATURE;
cbw->cbw_tag = (expected_tag = cbw_tag++);
cbw->cbw_data_transfer_length = 0;
- cbw->cbw_flags = 0x80; //IN
- cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
- cbw->cbw_cb_length = 12; //Alles null, also "Test unit ready"
+ cbw->cbw_flags = 0x80; //IN
+ cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
+ cbw->cbw_cb_length = 12; //Alles null, also "Test unit ready"
if (write_cmd(usbdev, pcbw) != USB_NO_ERROR) {
return 0;
@@ -395,14 +399,13 @@ static int msd_cdi_read(struct cdi_storage_device* strgdev, uint64_t start,
uintptr_t pb;
int bs = strgdev->block_size, error;
#ifdef WAIT_FOR_MSD_READY
- int j;
+ int i;
#endif
-// uint32_t i;
struct usb_device* usbdev = ((struct cdi_msd*) strgdev)->usb_device;
fdprintf("read(%i, %i)\n", (int) start, (int) count);
start += ((struct cdi_msd*) strgdev)->offset;
- if (cdi_alloc_phys_mem(bs, &vb, (void**) &pb) == -1) {
+ if (cdi_alloc_phys_mem(count * bs, &vb, (void**) &pb) == -1) {
dprintf("Blockspeicher konnte nicht allociert werden.\n");
return -1;
}
@@ -415,22 +418,19 @@ static int msd_cdi_read(struct cdi_storage_device* strgdev, uint64_t start,
__asm__ __volatile__ ("hlt");
#endif
}
- /*for (i = 0; i < count; i++)
- {*/
#ifdef WAIT_FOR_MSD_READY
- for (j = 0; !msd_ready(usbdev) && (j < 10); j++) {
+ for (i = 0; !msd_ready(usbdev) && (i < 10); i++) {
cdi_sleep_ms(20);
}
#endif
- error = msd_read(usbdev, start /* + i*/, count, pb, bs);
+ error = msd_read(usbdev, start, count, pb, count * bs);
if (error != USB_NO_ERROR) {
- dprintf("Lesefehler 0x%X bei Block %i.\n", error, 0);
+ dprintf("Lesefehler 0x%X bei Block %i.\n", error, start);
usbdev->locked = 0;
return -1;
}
- memcpy(buffer /* + i * bs*/, vb, count * bs);
- //}
+ memcpy(buffer, vb, count * bs);
usbdev->locked = 0;
return 0;
}
@@ -458,11 +458,11 @@ static uint32_t msd_read(struct usb_device* usbdev, uint32_t lba,
cbw->cbw_signature = CBW_SIGNATURE;
cbw->cbw_tag = (expected_tag = cbw_tag++);
cbw->cbw_data_transfer_length = length;
- cbw->cbw_flags = 0x80; //IN
- cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
+ cbw->cbw_flags = 0x80; //IN
+ cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
cbw->cbw_cb_length = 12;
cbw->cbw_cb[0] = MSC_CMD_READ10;
- cbw->cbw_cb[1] = 0; //LUN: 0
+ cbw->cbw_cb[1] = 0; //LUN: 0
cbw->cbw_cb[2] = (lba & 0xFF000000) >> 24;
cbw->cbw_cb[3] = (lba & 0x00FF0000) >> 16;
cbw->cbw_cb[4] = (lba & 0x0000FF00) >> 8;
@@ -484,7 +484,6 @@ static uint32_t msd_read(struct usb_device* usbdev, uint32_t lba,
.type_of_data = USB_TOD_DATA_IN,
};
- //Transaktionen eintragen
ep_size = msc->bulk_ep_in->max_packet_size;
for (i = 0; i < length; i += ep_size) {
in_packet.length = (length - i > ep_size) ? ep_size : length - i;
@@ -496,12 +495,6 @@ static uint32_t msd_read(struct usb_device* usbdev, uint32_t lba,
in_packet.datatoggle ^= 1;
}
- /*//Auf deren Ende warten
- for (i = 0; i < length; i += ep_size)
- {
-
- }*/
-
error = read_status(usbdev, expected_tag);
if (error != USB_NO_ERROR) {
return error;
@@ -561,71 +554,69 @@ static uint32_t msd_write(struct usb_device* usbdev, uint32_t lba,
uint16_t sectors, uintptr_t phys_buffer,
size_t length)
{
- /*struct msclass_data *msc;
- struct command_block_wrapper *cbw;
- struct command_status_wrapper *csw;
- uintptr_t pcbw, pcsw;
- uint32_t expected_tag;
- int error;
-
- if (cdi_alloc_phys_mem(sizeof(struct command_block_wrapper), (void **)&cbw, (void **)&pcbw) == -1)
- {
- return USB_TRIVIAL_ERROR;
- }
- if (cdi_alloc_phys_mem(sizeof(struct command_status_wrapper), (void **)&csw, (void **)&pcsw) == -1)
- {
- return USB_TRIVIAL_ERROR;
- }
- if (!phys_buffer || !length)
- {
- return USB_TRIVIAL_ERROR;
- }
- msc = (struct msclass_data *)usbdev->classd;
- memset(cbw, 0, 0x1F);
- cbw->cbw_signature = CBW_SIGNATURE;
- cbw->cbw_tag = (expected_tag = cbw_tag++);
- cbw->cbw_data_transfer_length = length;
- cbw->cbw_flags = 0x00; //OUT
- cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
- cbw->cbw_cb_length = 12;
- cbw->cbw_cb[0] = MSC_CMD_WRITE10;
- cbw->cbw_cb[1] = 0; //LUN: 0
- cbw->cbw_cb[2] = (lba & 0xFF000000) >> 24;
- cbw->cbw_cb[3] = (lba & 0x00FF0000) >> 16;
- cbw->cbw_cb[4] = (lba & 0x0000FF00) >> 8;
- cbw->cbw_cb[5] = lba & 0x000000FF;
- cbw->cbw_cb[7] = (sectors & 0x0000FF00) >> 8;
- cbw->cbw_cb[8] = sectors & 0x000000FF;
-
- error = write_cmd(usbdev, pcbw);
- if (error != USB_NO_ERROR)
- {
- return error;
- }
-
- struct usb_packet out_packet = {
- .type = PACKET_OUT,
- .endpoint = msc->bulk_ep_out->endpoint_address,
- .phys_data = phys_buffer,
- .length = length,
- .datatoggle = 0,
- .type_of_data = USB_TOD_DATA_OUT,
- };
-
- error = usb_do_packet(usbdev, &out_packet);
- if (error != USB_NO_ERROR)
- {
- return error;
- }
-
- error = read_status(usbdev, expected_tag);
- if (error != USB_NO_ERROR)
- {
- return error;
- }
-
- return USB_NO_ERROR;*/
- return USB_STALLED;
+ struct msclass_data* msc;
+ struct command_block_wrapper* cbw;
+ uintptr_t pcbw;
+ uint32_t expected_tag;
+ int error, i, ep_size;
+
+ if (cdi_alloc_phys_mem(sizeof(*cbw), (void**) &cbw,
+ (void**) &pcbw) == -1)
+ {
+ return USB_TRIVIAL_ERROR;
+ }
+ if (!phys_buffer || !length) {
+ return USB_TRIVIAL_ERROR;
+ }
+ msc = (struct msclass_data*) usbdev->classd;
+ memset(cbw, 0, 0x1F);
+ cbw->cbw_signature = CBW_SIGNATURE;
+ cbw->cbw_tag = (expected_tag = cbw_tag++);
+ cbw->cbw_data_transfer_length = length;
+ cbw->cbw_flags = 0x00; //OUT
+ cbw->cbw_lun = 0; //Was weiÃ? ich, wie viele LUNs datt Dingens hat?
+ cbw->cbw_cb_length = 12;
+ cbw->cbw_cb[0] = MSC_CMD_WRITE10;
+ cbw->cbw_cb[1] = 0; //LUN: 0
+ cbw->cbw_cb[2] = (lba & 0xFF000000) >> 24;
+ cbw->cbw_cb[3] = (lba & 0x00FF0000) >> 16;
+ cbw->cbw_cb[4] = (lba & 0x0000FF00) >> 8;
+ cbw->cbw_cb[5] = lba & 0x000000FF;
+ cbw->cbw_cb[7] = (sectors & 0x0000FF00) >> 8;
+ cbw->cbw_cb[8] = sectors & 0x000000FF;
+
+ error = write_cmd(usbdev, pcbw);
+ if (error != USB_NO_ERROR) {
+ return error;
+ }
+
+ struct usb_packet out_packet = {
+ .type = PACKET_OUT,
+ .endpoint = msc->bulk_ep_out->endpoint_address,
+ .phys_data = phys_buffer,
+ .length = 0,
+ .datatoggle = 0,
+ .type_of_data = USB_TOD_DATA_OUT,
+ };
+
+ //Transaktionen eintragen
+ ep_size = msc->bulk_ep_out->max_packet_size;
+ for (i = 0; i < length; i += ep_size) {
+ out_packet.length = (length - i > ep_size) ? ep_size : length - i;
+ error = usb_do_packet(usbdev, &out_packet);
+ if (error != USB_NO_ERROR) {
+ return error;
+ }
+ out_packet.phys_data += ep_size;
+ out_packet.datatoggle ^= 1;
+ }
+
+ error = read_status(usbdev, expected_tag);
+ if (error != USB_NO_ERROR) {
+ return error;
+ }
+
+ return USB_NO_ERROR;
}
static void get_partitions(struct cdi_storage_device* cdistrg)
@@ -662,8 +653,7 @@ static void get_partitions(struct cdi_storage_device* cdistrg)
break;
}
sprintf((char*) cdimsd->cdi_device.dev.name, "%sp%i",
- cdistrg->dev.name,
- j++);
+ cdistrg->dev.name, j++);
cdimsd->cdi_device.block_size = base_cdimsd->cdi_device.block_size;
cdimsd->cdi_device.block_count = partition[i].size;
_dprintf(" %s", cdimsd->cdi_device.dev.name);
--
1.6.3.3