mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-12 07:49:32 -05:00
implemented msd read
This commit is contained in:
parent
fc1b676ce6
commit
50859171f4
@ -31,7 +31,7 @@ SdOverUsbView::SdOverUsbView(NavigationView& nav) : nav_ (nav) {
|
|||||||
sdcStop(&SDCD1);
|
sdcStop(&SDCD1);
|
||||||
|
|
||||||
portapack::shutdown();
|
portapack::shutdown();
|
||||||
m4_init(portapack::spi_flash::image_tag_usb_sd, portapack::memory::map::m4_code, true);
|
m4_init(portapack::spi_flash::image_tag_usb_sd, portapack::memory::map::m4_code, false);
|
||||||
//m4_init(portapack::spi_flash::image_tag_hackrf, portapack::memory::map::m4_code_hackrf, true);
|
//m4_init(portapack::spi_flash::image_tag_hackrf, portapack::memory::map::m4_code_hackrf, true);
|
||||||
m0_halt(); /* will not return*/
|
m0_halt(); /* will not return*/
|
||||||
//baseband::run_image();
|
//baseband::run_image();
|
||||||
|
@ -515,7 +515,7 @@ set(MODE_CPPSRC
|
|||||||
)
|
)
|
||||||
DeclareTargets(PFUT flash_utility)
|
DeclareTargets(PFUT flash_utility)
|
||||||
|
|
||||||
### SD over USB ${PATH_HACKRF_FIRMWARE}
|
### SD over USB
|
||||||
|
|
||||||
set(MODE_INCDIR
|
set(MODE_INCDIR
|
||||||
${HACKRF_PATH}/firmware
|
${HACKRF_PATH}/firmware
|
||||||
@ -526,17 +526,18 @@ set(MODE_CPPSRC
|
|||||||
sd_over_usb/proc_sd_over_usb.cpp
|
sd_over_usb/proc_sd_over_usb.cpp
|
||||||
|
|
||||||
sd_over_usb/scsi.c
|
sd_over_usb/scsi.c
|
||||||
|
sd_over_usb/diskio.c
|
||||||
sd_over_usb/sd_over_usb.c
|
sd_over_usb/sd_over_usb.c
|
||||||
sd_over_usb/usb_descriptor.c
|
sd_over_usb/usb_descriptor.c
|
||||||
sd_over_usb/usb_device.c
|
sd_over_usb/usb_device.c
|
||||||
sd_over_usb/usb_endpoint.c
|
sd_over_usb/usb_endpoint.c
|
||||||
sd_over_usb/usb.c
|
sd_over_usb/usb.c
|
||||||
|
sd_over_usb/hackrf_core.c
|
||||||
|
|
||||||
${HACKRF_PATH}/firmware/common/usb_queue.c
|
${HACKRF_PATH}/firmware/common/usb_queue.c
|
||||||
${HACKRF_PATH}/firmware/common/usb_request.c
|
${HACKRF_PATH}/firmware/common/usb_request.c
|
||||||
${HACKRF_PATH}/firmware/common/usb_standard_request.c
|
${HACKRF_PATH}/firmware/common/usb_standard_request.c
|
||||||
${HACKRF_PATH}/firmware/common/platform_detect.c
|
${HACKRF_PATH}/firmware/common/platform_detect.c
|
||||||
${HACKRF_PATH}/firmware/common/hackrf_core.c
|
|
||||||
${HACKRF_PATH}/firmware/common/gpio_lpc.c
|
${HACKRF_PATH}/firmware/common/gpio_lpc.c
|
||||||
${HACKRF_PATH}/firmware/common/firmware_info.c
|
${HACKRF_PATH}/firmware/common/firmware_info.c
|
||||||
${HACKRF_PATH}/firmware/common/si5351c.c
|
${HACKRF_PATH}/firmware/common/si5351c.c
|
||||||
@ -558,7 +559,6 @@ set(MODE_CPPSRC
|
|||||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/scu.c
|
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/scu.c
|
||||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/timer.c
|
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/timer.c
|
||||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/i2c.c
|
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/i2c.c
|
||||||
|
|
||||||
)
|
)
|
||||||
DeclareTargets(PUSB sd_over_usb)
|
DeclareTargets(PUSB sd_over_usb)
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
* @brief Enables the SDC subsystem.
|
* @brief Enables the SDC subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||||
#ifdef BASEBAND_flash_utility
|
#if defined(BASEBAND_flash_utility) || defined(BASEBAND_sd_over_usb)
|
||||||
#define HAL_USE_SDC TRUE
|
#define HAL_USE_SDC TRUE
|
||||||
#else
|
#else
|
||||||
#define HAL_USE_SDC FALSE
|
#define HAL_USE_SDC FALSE
|
||||||
|
12
firmware/baseband/sd_over_usb/diskio.c
Normal file
12
firmware/baseband/sd_over_usb/diskio.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "diskio.h"
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
uint32_t get_capacity(void) {
|
||||||
|
return mmcsdGetCardCapacity(&SDCD1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t read_block(uint32_t startblk, uint8_t *buf, uint32_t n) {
|
||||||
|
return sdcRead(&SDCD1, startblk, buf, n);
|
||||||
|
}
|
10
firmware/baseband/sd_over_usb/diskio.h
Normal file
10
firmware/baseband/sd_over_usb/diskio.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __DISKIO_H__
|
||||||
|
#define __DISKIO_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <chtypes.h>
|
||||||
|
|
||||||
|
uint32_t get_capacity(void);
|
||||||
|
bool_t read_block(uint32_t startblk, uint8_t *buf, uint32_t n);
|
||||||
|
|
||||||
|
#endif /* __DISKIO_H__ */
|
1089
firmware/baseband/sd_over_usb/hackrf_core.c
Normal file
1089
firmware/baseband/sd_over_usb/hackrf_core.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
#include "event_m4.hpp"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void start_usb(void);
|
void start_usb(void);
|
||||||
@ -40,34 +39,22 @@ CH_IRQ_HANDLER(Vector60) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//uint8_t buf[512];
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
//EventDispatcher event_dispatcher { std::make_unique<USBProcessor>() };
|
|
||||||
|
|
||||||
//HALT_UNTIL_DEBUGGING();
|
sdcStart(&SDCD1, nullptr);
|
||||||
|
if (sdcConnect(&SDCD1) == CH_FAILED) chDbgPanic("no sd card #1");
|
||||||
|
|
||||||
|
// memset(&buf[0], 0, 512);
|
||||||
|
// if (sdcRead(&SDCD1, 0, &buf[0], 1) == CH_FAILED) chDbgPanic("no sd card #2");
|
||||||
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.PD = 1;
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.AUTOBLOCK = 1;
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.CLK_SEL = 0x06;
|
|
||||||
//
|
|
||||||
//while (LPC_CGU->PLL0USB_STAT.LOCK) {}
|
|
||||||
//
|
|
||||||
//LPC_CGU->PLL0USB_MDIV = 0x06167FFA; // 0x71A7FAA; //
|
|
||||||
//LPC_CGU->PLL0USB_NP_DIV = 0x00302062;
|
|
||||||
//
|
|
||||||
////LPC_CGU->PLL0USB_CTRL.PD |= 1;
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.DIRECTI = 1;
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.DIRECTO = 1;
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.CLKEN = 1;
|
|
||||||
//
|
|
||||||
//LPC_CGU->PLL0USB_CTRL.PD = 0;
|
|
||||||
//
|
|
||||||
//while (!(LPC_CGU->PLL0USB_STAT.LOCK)) {}
|
|
||||||
////chThdSleepMilliseconds(800);
|
|
||||||
//
|
|
||||||
//LPC_CGU->BASE_USB0_CLK.AUTOBLOCK = 1;
|
|
||||||
//LPC_CGU->BASE_USB0_CLK.CLK_SEL = 0x07;
|
|
||||||
|
|
||||||
start_usb();
|
start_usb();
|
||||||
|
|
||||||
|
// memset(&buf[0], 0, 512);
|
||||||
|
// if (sdcRead(&SDCD1, 0, &buf[0], 1) == CH_FAILED) chDbgPanic("no sd card #3");
|
||||||
|
|
||||||
//event_dispatcher.run();
|
//event_dispatcher.run();
|
||||||
while (true) {
|
while (true) {
|
||||||
usb_transfer();
|
usb_transfer();
|
||||||
|
@ -1,210 +1,125 @@
|
|||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
|
#include "diskio.h"
|
||||||
|
|
||||||
#define HALT_UNTIL_DEBUGGING() \
|
#define HALT_UNTIL_DEBUGGING() \
|
||||||
while (!((*(volatile uint32_t *)0xE000EDF0) & (1 << 0))) {} \
|
while (!((*(volatile uint32_t *)0xE000EDF0) & (1 << 0))) {} \
|
||||||
__asm__ __volatile__("bkpt 1")
|
__asm__ __volatile__("bkpt 1")
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t peripheral;
|
|
||||||
uint8_t removable;
|
|
||||||
uint8_t version;
|
|
||||||
uint8_t response_data_format;
|
|
||||||
uint8_t additional_length;
|
|
||||||
uint8_t sccstp;
|
|
||||||
uint8_t bqueetc;
|
|
||||||
uint8_t cmdque;
|
|
||||||
uint8_t vendorID[8];
|
|
||||||
uint8_t productID[16];
|
|
||||||
uint8_t productRev[4];
|
|
||||||
} scsi_inquiry_response_t;
|
|
||||||
|
|
||||||
|
volatile bool usb_bulk_block_send = false;
|
||||||
|
|
||||||
static const scsi_inquiry_response_t default_scsi_inquiry_response = {
|
void usb_bulk_block_cb(void* user_data, unsigned int bytes_transferred) {
|
||||||
0x00, /* direct access block device */
|
usb_bulk_block_send = true;
|
||||||
0x80, /* removable */
|
|
||||||
0x04, /* SPC-2 */
|
|
||||||
0x02, /* response data format */
|
|
||||||
0x20, /* response has 0x20 + 4 bytes */
|
|
||||||
0x00,
|
|
||||||
0x00,
|
|
||||||
0x00,
|
|
||||||
"Mayhem",
|
|
||||||
"Mass Storage",
|
|
||||||
{'v','1','.','6'}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
(void)user_data;
|
||||||
uint32_t signature;
|
(void)bytes_transferred;
|
||||||
uint32_t tag;
|
|
||||||
uint32_t data_residue;
|
|
||||||
uint8_t status;
|
|
||||||
} __attribute__((packed)) msd_csw_t;
|
|
||||||
|
|
||||||
#define MSD_CBW_SIGNATURE 0x43425355
|
|
||||||
#define MSD_CSW_SIGNATURE 0x53425355
|
|
||||||
|
|
||||||
// void handle_inquiry_4(void* user_data, unsigned int bytes_transferred) {
|
|
||||||
// HALT_UNTIL_DEBUGGING();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void handle_inquiry_3(void* user_data, unsigned int bytes_transferred)
|
|
||||||
// {
|
|
||||||
// //msd_cbw_t *msd_cbw_data = (msd_cbw_t *)user_data;
|
|
||||||
|
|
||||||
// //HALT_UNTIL_DEBUGGING();
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
volatile bool inquiry_stage_one_send = false;
|
|
||||||
void inquiry_cb(void* user_data, unsigned int bytes_transferred)
|
|
||||||
{
|
|
||||||
inquiry_stage_one_send = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_inquiry(msd_cbw_t *msd_cbw_data) {
|
void usb_send_bulk(void* const data, const uint32_t maximum_length) {
|
||||||
inquiry_stage_one_send = false;
|
usb_bulk_block_send = false;
|
||||||
memcpy(&usb_bulk_buffer[0], &default_scsi_inquiry_response, sizeof(scsi_inquiry_response_t));
|
|
||||||
usb_transfer_schedule_block(
|
usb_transfer_schedule_block(
|
||||||
&usb_endpoint_bulk_in,
|
&usb_endpoint_bulk_in,
|
||||||
&usb_bulk_buffer[0],
|
data,
|
||||||
sizeof(scsi_inquiry_response_t),
|
maximum_length,
|
||||||
inquiry_cb,
|
usb_bulk_block_cb,
|
||||||
msd_cbw_data);
|
NULL);
|
||||||
|
|
||||||
while (!inquiry_stage_one_send);
|
while (!usb_bulk_block_send);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_send_csw(msd_cbw_t *msd_cbw_data, uint8_t status) {
|
||||||
msd_csw_t csw = {
|
msd_csw_t csw = {
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
.signature = MSD_CSW_SIGNATURE,
|
||||||
.tag = msd_cbw_data->tag,
|
.tag = msd_cbw_data->tag,
|
||||||
.data_residue = 0,
|
.data_residue = 0,
|
||||||
.status = 0
|
.status = status
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
memcpy(&usb_bulk_buffer[0], &csw, sizeof(msd_csw_t));
|
||||||
usb_transfer_schedule_block(
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(msd_csw_t));
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
uint8_t handle_inquiry(msd_cbw_t *msd_cbw_data) {
|
||||||
uint8_t header[4];
|
(void)msd_cbw_data;
|
||||||
uint8_t blocknum[4];
|
|
||||||
uint8_t blocklen[4];
|
|
||||||
} scsi_read_format_capacities_response_t;
|
|
||||||
|
|
||||||
volatile bool capacities_stage_one_send = false;
|
scsi_inquiry_response_t ret = {
|
||||||
void capacities_cb(void* user_data, unsigned int bytes_transferred)
|
0x00, /* direct access block device */
|
||||||
{
|
0x80, /* removable */
|
||||||
capacities_stage_one_send = true;
|
0x00, //0x04, /* SPC-2 */
|
||||||
|
0x00, //0x02, /* response data format */
|
||||||
|
0x20, /* response has 0x20 + 4 bytes */
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
"Mayhem",
|
||||||
|
"Portapack MSD",
|
||||||
|
{'v','1','.','6'}
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_inquiry_response_t));
|
||||||
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_inquiry_response_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_format_capacities(msd_cbw_t *msd_cbw_data) {
|
uint8_t handle_inquiry_serial_number(msd_cbw_t *msd_cbw_data) {
|
||||||
|
(void)msd_cbw_data;
|
||||||
|
|
||||||
|
scsi_unit_serial_number_inquiry_response_t ret = {
|
||||||
|
.peripheral = 0x00,
|
||||||
|
.page_code = 0x80,
|
||||||
|
.reserved = 0,
|
||||||
|
.page_length = 0x08,
|
||||||
|
.serialNumber = "Mayhem"
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_unit_serial_number_inquiry_response_t));
|
||||||
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_unit_serial_number_inquiry_response_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t read_format_capacities(msd_cbw_t *msd_cbw_data) {
|
||||||
uint16_t len = msd_cbw_data->cmd_data[7] << 8 | msd_cbw_data->cmd_data[8];
|
uint16_t len = msd_cbw_data->cmd_data[7] << 8 | msd_cbw_data->cmd_data[8];
|
||||||
|
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
|
size_t num_blocks = get_capacity();
|
||||||
|
|
||||||
scsi_read_format_capacities_response_t ret = {
|
scsi_read_format_capacities_response_t ret = {
|
||||||
.header = {0, 0, 0, 1 * 8 /* num_entries * 8 */},
|
.header = {0, 0, 0, 1 * 8 /* num_entries * 8 */},
|
||||||
.blocknum = {0, 0, (1024 * 8) >> 8, 0}, // 32GB
|
.blocknum = {((num_blocks) >> 24)& 0xff, ((num_blocks) >> 16)& 0xff, ((num_blocks) >> 8)& 0xff, num_blocks & 0xff},
|
||||||
.blocklen = {0b10 /* formated */, 0, (512) >> 8, 0}
|
.blocklen = {0b10 /* formated */, 0, (512) >> 8, 0},
|
||||||
|
// .blocknum2 = {((num_blocks) >> 24)& 0xff, ((num_blocks) >> 16)& 0xff, ((num_blocks) >> 8)& 0xff, num_blocks & 0xff},
|
||||||
|
// .blocklen2 = {0 /* formated */, 0, (512) >> 8, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
capacities_stage_one_send = false;
|
|
||||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_format_capacities_response_t));
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_format_capacities_response_t));
|
||||||
usb_transfer_schedule_block(
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_read_format_capacities_response_t));
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0],
|
|
||||||
sizeof(scsi_inquiry_response_t),
|
|
||||||
capacities_cb,
|
|
||||||
msd_cbw_data);
|
|
||||||
|
|
||||||
while (!capacities_stage_one_send);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
msd_csw_t csw = {
|
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
uint8_t read_capacity10(msd_cbw_t *msd_cbw_data) {
|
||||||
uint32_t last_block_addr;
|
(void)msd_cbw_data;
|
||||||
uint32_t block_size;
|
|
||||||
} scsi_read_capacity10_response_t;
|
|
||||||
|
|
||||||
volatile bool capacity10_stage_one_send = false;
|
size_t num_blocks = get_capacity();
|
||||||
void capacity10_cb(void* user_data, unsigned int bytes_transferred)
|
|
||||||
{
|
|
||||||
capacity10_stage_one_send = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_capacity10(msd_cbw_t *msd_cbw_data) {
|
|
||||||
capacity10_stage_one_send = false;
|
|
||||||
|
|
||||||
scsi_read_capacity10_response_t ret = {
|
scsi_read_capacity10_response_t ret = {
|
||||||
.last_block_addr = cpu_to_be32(8 * 1024 * 1024 - 1),
|
.last_block_addr = cpu_to_be32(num_blocks - 1),
|
||||||
.block_size = cpu_to_be32(512)
|
.block_size = cpu_to_be32(512)
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_capacity10_response_t));
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_capacity10_response_t));
|
||||||
usb_transfer_schedule_block(
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_read_capacity10_response_t));
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0],
|
|
||||||
sizeof(scsi_read_capacity10_response_t),
|
|
||||||
capacity10_cb,
|
|
||||||
msd_cbw_data);
|
|
||||||
|
|
||||||
while (!capacity10_stage_one_send);
|
|
||||||
|
|
||||||
msd_csw_t csw = {
|
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t request_sense(msd_cbw_t *msd_cbw_data) {
|
||||||
typedef struct {
|
(void)msd_cbw_data;
|
||||||
uint8_t byte[18];
|
|
||||||
} scsi_sense_response_t;
|
|
||||||
|
|
||||||
volatile bool sense_stage_one_send = false;
|
|
||||||
void sense_cb(void* user_data, unsigned int bytes_transferred)
|
|
||||||
{
|
|
||||||
sense_stage_one_send = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void request_sense(msd_cbw_t *msd_cbw_data) {
|
|
||||||
sense_stage_one_send = false;
|
|
||||||
|
|
||||||
scsi_sense_response_t ret = {
|
scsi_sense_response_t ret = {
|
||||||
.byte = { 0x70, 0, SCSI_SENSE_KEY_GOOD, 0,
|
.byte = { 0x70, 0, SCSI_SENSE_KEY_GOOD, 0,
|
||||||
@ -215,83 +130,28 @@ void request_sense(msd_cbw_t *msd_cbw_data) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_sense_response_t));
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_sense_response_t));
|
||||||
usb_transfer_schedule_block(
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_sense_response_t));
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0],
|
|
||||||
sizeof(scsi_sense_response_t),
|
|
||||||
sense_cb,
|
|
||||||
msd_cbw_data);
|
|
||||||
|
|
||||||
while (!sense_stage_one_send);
|
return 0;
|
||||||
|
|
||||||
msd_csw_t csw = {
|
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
uint8_t mode_sense6 (msd_cbw_t *msd_cbw_data) {
|
||||||
uint8_t byte[4];
|
(void)msd_cbw_data;
|
||||||
} scsi_mode_sense6_response_t;
|
|
||||||
|
|
||||||
volatile bool sense6_stage_one_send = false;
|
scsi_mode_sense6_response_t ret = {
|
||||||
void sense6_cb(void* user_data, unsigned int bytes_transferred)
|
|
||||||
{
|
|
||||||
sense6_stage_one_send = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mode_sense6 (msd_cbw_t *msd_cbw_data) {
|
|
||||||
sense6_stage_one_send = false;
|
|
||||||
|
|
||||||
scsi_mode_sense6_response_t ret = {
|
|
||||||
.byte = {
|
.byte = {
|
||||||
sizeof(scsi_mode_sense6_response_t) - 1,
|
sizeof(scsi_mode_sense6_response_t) - 1,
|
||||||
0,
|
0,
|
||||||
0x01 << 7, // 0 for not write protected
|
0, // 0x01 << 7, // 0 for not write protected
|
||||||
0 }
|
0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_mode_sense6_response_t));
|
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_mode_sense6_response_t));
|
||||||
usb_transfer_schedule_block(
|
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_mode_sense6_response_t));
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0],
|
|
||||||
sizeof(scsi_mode_sense6_response_t),
|
|
||||||
sense6_cb,
|
|
||||||
msd_cbw_data);
|
|
||||||
|
|
||||||
while (!sense6_stage_one_send);
|
return 0;
|
||||||
|
|
||||||
msd_csw_t csw = {
|
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t first_lba;
|
|
||||||
uint16_t blk_cnt;
|
|
||||||
} data_request_t;
|
|
||||||
|
|
||||||
static data_request_t decode_data_request(const uint8_t *cmd) {
|
static data_request_t decode_data_request(const uint8_t *cmd) {
|
||||||
|
|
||||||
data_request_t req;
|
data_request_t req;
|
||||||
@ -307,122 +167,102 @@ static data_request_t decode_data_request(const uint8_t *cmd) {
|
|||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile uint32_t read10_blocks_send = 0;
|
uint8_t data_read10(msd_cbw_t *msd_cbw_data) {
|
||||||
void read10_cb(void* user_data, unsigned int bytes_transferred)
|
data_request_t req = decode_data_request(msd_cbw_data->cmd_data);
|
||||||
{
|
|
||||||
read10_blocks_send++;
|
for (size_t block_index = 0; block_index < req.blk_cnt; block_index++) {
|
||||||
|
read_block(req.first_lba + block_index, &usb_bulk_buffer[0], 1 /* n blocks */);
|
||||||
|
usb_send_bulk(&usb_bulk_buffer[0], 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
volatile uint32_t write10_blocks_send = 0;
|
||||||
|
void write10_cb(void* user_data, unsigned int bytes_transferred)
|
||||||
|
{
|
||||||
|
write10_blocks_send++;
|
||||||
|
|
||||||
|
(void)user_data;
|
||||||
|
(void)bytes_transferred;
|
||||||
|
}
|
||||||
|
|
||||||
void data_read10(msd_cbw_t *msd_cbw_data) {
|
uint8_t data_write10(msd_cbw_t *msd_cbw_data) {
|
||||||
read10_blocks_send = 0;
|
write10_blocks_send = 0;
|
||||||
|
|
||||||
data_request_t req = decode_data_request(msd_cbw_data->cmd_data);
|
data_request_t req = decode_data_request(msd_cbw_data->cmd_data);
|
||||||
|
|
||||||
for (size_t block_index = 0; block_index < req.blk_cnt; block_index++) {
|
for (size_t block_index = 0; block_index < req.blk_cnt; block_index++) {
|
||||||
memset(&usb_bulk_buffer[0], 0, 512);
|
|
||||||
|
|
||||||
usb_transfer_schedule_block(
|
usb_transfer_schedule_block(
|
||||||
&usb_endpoint_bulk_in,
|
&usb_endpoint_bulk_out,
|
||||||
&usb_bulk_buffer[0],
|
&usb_bulk_buffer[0],
|
||||||
512,
|
512,
|
||||||
read10_cb,
|
write10_cb,
|
||||||
msd_cbw_data);
|
msd_cbw_data);
|
||||||
|
|
||||||
while (read10_blocks_send <= block_index);
|
while (write10_blocks_send <= block_index);
|
||||||
|
|
||||||
|
//TODO: write to SD
|
||||||
}
|
}
|
||||||
|
|
||||||
msd_csw_t csw = {
|
return 0;
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void test_unit_ready(msd_cbw_t *msd_cbw_data) {
|
|
||||||
msd_csw_t csw = {
|
|
||||||
.signature = MSD_CSW_SIGNATURE,
|
|
||||||
.tag = msd_cbw_data->tag,
|
|
||||||
.data_residue = 0,
|
|
||||||
.status = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&usb_bulk_buffer[0x4000], &csw, sizeof(msd_csw_t));
|
|
||||||
usb_transfer_schedule_block(
|
|
||||||
&usb_endpoint_bulk_in,
|
|
||||||
&usb_bulk_buffer[0x4000],
|
|
||||||
sizeof(msd_csw_t),
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scsi_command(msd_cbw_t *msd_cbw_data) {
|
void scsi_command(msd_cbw_t *msd_cbw_data) {
|
||||||
|
uint8_t status = 1;
|
||||||
|
|
||||||
switch (msd_cbw_data->cmd_data[0]) {
|
switch (msd_cbw_data->cmd_data[0]) {
|
||||||
case SCSI_CMD_INQUIRY:
|
case SCSI_CMD_INQUIRY:
|
||||||
handle_inquiry(msd_cbw_data);
|
//status = handle_inquiry(msd_cbw_data);
|
||||||
|
if ((msd_cbw_data->cmd_data[1] & 0b1) && msd_cbw_data->cmd_data[2] == 0x80) {
|
||||||
|
status = handle_inquiry_serial_number(msd_cbw_data);
|
||||||
|
}
|
||||||
|
else if ((msd_cbw_data->cmd_data[1] & 0b11) || msd_cbw_data->cmd_data[2] != 0) {
|
||||||
|
//TODO: implement sense
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status = handle_inquiry(msd_cbw_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
case SCSI_CMD_REQUEST_SENSE:
|
||||||
|
status = request_sense(msd_cbw_data);
|
||||||
|
break;
|
||||||
|
|
||||||
case SCSI_CMD_REQUEST_SENSE:
|
case SCSI_CMD_READ_CAPACITY_10:
|
||||||
request_sense(msd_cbw_data);
|
status = read_capacity10(msd_cbw_data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_CMD_READ_CAPACITY_10:
|
case SCSI_CMD_READ_10:
|
||||||
read_capacity10(msd_cbw_data);
|
status = data_read10(msd_cbw_data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_CMD_READ_10:
|
case SCSI_CMD_WRITE_10:
|
||||||
data_read10(msd_cbw_data);
|
status = data_write10(msd_cbw_data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
case SCSI_CMD_TEST_UNIT_READY:
|
||||||
case SCSI_CMD_WRITE_10:
|
status = 0;
|
||||||
ret = data_read_write10(scsip, cmd);
|
break;
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case SCSI_CMD_TEST_UNIT_READY:
|
|
||||||
test_unit_ready(msd_cbw_data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||||
test_unit_ready(msd_cbw_data);
|
status = 0;
|
||||||
// ret = cmd_ignored(scsip, cmd);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_MODE_SENSE_6:
|
|
||||||
mode_sense6(msd_cbw_data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_READ_FORMAT_CAPACITIES:
|
|
||||||
read_format_capacities(msd_cbw_data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_VERIFY_10:
|
|
||||||
test_unit_ready(msd_cbw_data);
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
default:
|
|
||||||
ret = cmd_unhandled(scsip, cmd);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (ret == SCSI_SUCCESS)
|
|
||||||
// set_sense_ok(scsip);
|
|
||||||
|
|
||||||
|
case SCSI_CMD_MODE_SENSE_6:
|
||||||
|
status = mode_sense6(msd_cbw_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_CMD_READ_FORMAT_CAPACITIES:
|
||||||
|
status = read_format_capacities(msd_cbw_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_CMD_VERIFY_10:
|
||||||
|
status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usb_send_csw(msd_cbw_data, status);
|
||||||
}
|
}
|
@ -13,6 +13,9 @@
|
|||||||
#include "hackrf_core.h"
|
#include "hackrf_core.h"
|
||||||
#include "usb_bulk_buffer.h"
|
#include "usb_bulk_buffer.h"
|
||||||
|
|
||||||
|
#define MSD_CBW_SIGNATURE 0x43425355
|
||||||
|
#define MSD_CSW_SIGNATURE 0x53425355
|
||||||
|
|
||||||
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
||||||
#define SCSI_CMD_REQUEST_SENSE 0x03
|
#define SCSI_CMD_REQUEST_SENSE 0x03
|
||||||
#define SCSI_CMD_INQUIRY 0x12
|
#define SCSI_CMD_INQUIRY 0x12
|
||||||
@ -71,6 +74,67 @@ typedef struct {
|
|||||||
uint8_t cmd_data[16];
|
uint8_t cmd_data[16];
|
||||||
} __attribute__((packed)) msd_cbw_t;
|
} __attribute__((packed)) msd_cbw_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t peripheral;
|
||||||
|
uint8_t removable;
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t response_data_format;
|
||||||
|
uint8_t additional_length;
|
||||||
|
uint8_t sccstp;
|
||||||
|
uint8_t bqueetc;
|
||||||
|
uint8_t cmdque;
|
||||||
|
uint8_t vendorID[8];
|
||||||
|
uint8_t productID[16];
|
||||||
|
uint8_t productRev[4];
|
||||||
|
} scsi_inquiry_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t signature;
|
||||||
|
uint32_t tag;
|
||||||
|
uint32_t data_residue;
|
||||||
|
uint8_t status;
|
||||||
|
} __attribute__((packed)) msd_csw_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t header[4];
|
||||||
|
uint8_t blocknum[4];
|
||||||
|
uint8_t blocklen[4];
|
||||||
|
} scsi_read_format_capacities_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t header[4];
|
||||||
|
uint8_t blocknum[4];
|
||||||
|
uint8_t blocklen[4];
|
||||||
|
uint8_t blocknum2[4];
|
||||||
|
uint8_t blocklen2[4];
|
||||||
|
} scsi_read_format_capacities_double_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t last_block_addr;
|
||||||
|
uint32_t block_size;
|
||||||
|
} scsi_read_capacity10_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t byte[18];
|
||||||
|
} scsi_sense_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t byte[4];
|
||||||
|
} scsi_mode_sense6_response_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t first_lba;
|
||||||
|
uint16_t blk_cnt;
|
||||||
|
} data_request_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t peripheral;
|
||||||
|
uint8_t page_code;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint8_t page_length;
|
||||||
|
uint8_t serialNumber[8];
|
||||||
|
} scsi_unit_serial_number_inquiry_response_t;
|
||||||
|
|
||||||
static inline uint16_t bswap_16(const uint16_t x)
|
static inline uint16_t bswap_16(const uint16_t x)
|
||||||
__attribute__ ((warn_unused_result))
|
__attribute__ ((warn_unused_result))
|
||||||
__attribute__ ((const))
|
__attribute__ ((const))
|
||||||
|
@ -94,16 +94,16 @@ usb_request_status_t usb_vendor_request(
|
|||||||
{
|
{
|
||||||
usb_request_status_t status = USB_REQUEST_STATUS_STALL;
|
usb_request_status_t status = USB_REQUEST_STATUS_STALL;
|
||||||
|
|
||||||
volatile uint_fast8_t address = endpoint->address;
|
// volatile uint_fast8_t address = endpoint->address;
|
||||||
volatile uint8_t request = endpoint->setup.request;
|
volatile uint8_t request = endpoint->setup.request;
|
||||||
volatile uint32_t b = 0;
|
// volatile uint32_t b = 0;
|
||||||
|
|
||||||
if (request == 25) { // unknown code
|
if (request == 25) { // unknown code
|
||||||
return report_magic_scsi(endpoint, stage);
|
return report_magic_scsi(endpoint, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
b = request + (address << 16);
|
// b = request + (address << 16);
|
||||||
HALT_UNTIL_DEBUGGING();
|
// HALT_UNTIL_DEBUGGING();
|
||||||
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -115,16 +115,15 @@ usb_request_status_t usb_class_request(
|
|||||||
{
|
{
|
||||||
usb_request_status_t status = USB_REQUEST_STATUS_STALL;
|
usb_request_status_t status = USB_REQUEST_STATUS_STALL;
|
||||||
|
|
||||||
volatile uint_fast8_t address = endpoint->address;
|
|
||||||
volatile uint8_t request = endpoint->setup.request;
|
volatile uint8_t request = endpoint->setup.request;
|
||||||
volatile uint32_t b = 0;
|
// volatile uint32_t b = 0;
|
||||||
|
|
||||||
if (request == 0xFE) {
|
if (request == 0xFE) {
|
||||||
return report_max_lun(endpoint, stage);
|
return report_max_lun(endpoint, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
b = request + (address << 16);
|
// b = request + (address << 16);
|
||||||
HALT_UNTIL_DEBUGGING();
|
// HALT_UNTIL_DEBUGGING();
|
||||||
|
|
||||||
// if (address == 0x80) {
|
// if (address == 0x80) {
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ usb_request_status_t usb_class_request(
|
|||||||
|
|
||||||
|
|
||||||
// HALT_UNTIL_DEBUGGING();
|
// HALT_UNTIL_DEBUGGING();
|
||||||
return status + b;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const usb_request_handlers_t usb_request_handlers = {
|
const usb_request_handlers_t usb_request_handlers = {
|
||||||
@ -168,7 +167,7 @@ void usb_configuration_changed(usb_device_t* const device)
|
|||||||
void start_usb(void) {
|
void start_usb(void) {
|
||||||
detect_hardware_platform();
|
detect_hardware_platform();
|
||||||
pin_setup();
|
pin_setup();
|
||||||
cpu_clock_init();
|
cpu_clock_init(); // required
|
||||||
|
|
||||||
usb_set_configuration_changed_cb(usb_configuration_changed);
|
usb_set_configuration_changed_cb(usb_configuration_changed);
|
||||||
usb_peripheral_reset();
|
usb_peripheral_reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user