65 unsigned int interface = usbblk->func->
interface[0];
75 DBGC ( usbblk,
"USBBLK %s could not issue reset: %s\n",
82 DBGC ( usbblk,
"USBBLK %s could not open bulk OUT: %s\n",
89 DBGC ( usbblk,
"USBBLK %s could not reset bulk OUT: %s\n",
96 DBGC ( usbblk,
"USBBLK %s could not open bulk IN: %s\n",
103 DBGC ( usbblk,
"USBBLK %s could not reset bulk IN: %s\n",
157 assert ( ! (
cmd->scsi.data_in_len &&
cmd->scsi.data_out_len ) );
160 iobuf =
alloc_iob (
sizeof ( *wrapper ) );
167 wrapper =
iob_put ( iobuf,
sizeof ( *wrapper ) );
168 memset ( wrapper, 0,
sizeof ( *wrapper ) );
171 if (
cmd->scsi.data_out_len ) {
178 wrapper->
cblen =
sizeof ( wrapper->
cb );
179 memcpy ( wrapper->
cb, &
cmd->scsi.cdb, sizeof ( wrapper->
cb ) );
183 DBGC ( usbblk,
"USBBLK %s bulk OUT could not issue command: "
212 len = (
cmd->scsi.data_out_len -
cmd->offset );
226 (
cmd->scsi.data_out +
cmd->offset ),
len );
230 DBGC ( usbblk,
"USBBLK %s bulk OUT could not send data: %s\n",
260 while ( (
cmd->offset <
cmd->scsi.data_out_len ) &&
291 DBGC ( usbblk,
"USBBLK %s bulk OUT failed: %s\n",
297 if (
cmd->offset <
cmd->scsi.data_out_len )
365 if (
len <
sizeof ( *
stat ) ) {
366 DBGC ( usbblk,
"USBBLK %s bulk IN malformed status:\n",
375 DBGC ( usbblk,
"USBBLK %s bulk IN invalid signature %08x:\n",
383 DBGC ( usbblk,
"USBBLK %s bulk IN tag mismatch (got %08x, "
391 if (
stat->status ) {
392 DBGC ( usbblk,
"USBBLK %s bulk IN status %02x:\n",
399 if (
stat->residue ) {
400 DBGC ( usbblk,
"USBBLK %s bulk IN residue %#x:\n",
428 remaining =
sizeof ( *stat );
429 if (
cmd->scsi.data_in_len ) {
431 remaining += (
cmd->scsi.data_in_len -
cmd->offset );
466 DBGC ( usbblk,
"USBBLK %s bulk IN failed: %s\n",
475 if (
cmd->scsi.data_in_len ) {
477 remaining = (
cmd->scsi.data_in_len -
cmd->offset );
479 if (
len > remaining )
564 DBGC ( usbblk,
"USBBLK %s closing for error recovery\n",
588 DBGC ( usbblk,
"USBBLK %s cannot support multiple commands\n",
596 DBGC ( usbblk,
"USBBLK %s cannot support bidirectional "
598 goto err_bidirectional;
651 return (
cmd->tag ? 0 : 1 );
785 DBGC ( usbblk,
"USBBLK %s could not open SCSI device: %s\n",
824 usbblk =
zalloc (
sizeof ( *usbblk ) );
841 DBGC ( usbblk,
"USBBLK %s missing interface descriptor\n",
850 DBGC ( usbblk,
"USBBLK %s could not describe bulk OUT: %s\n",
856 DBGC ( usbblk,
"USBBLK %s could not describe bulk IN: %s\n",
898 USB_ID ( 0xffff, 0xffff,
"usbblk",
"USB block device", 0 ),
#define NULL
NULL pointer (VOID *)
struct arbelprm_rc_send_wqe rc
#define assert(condition)
Assert a condition at run-time.
uint32_t stat
Completion status.
uint8_t lun
Logical Unit Number.
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
uint8_t data[48]
Additional event data.
struct ena_llq_option desc
Descriptor counts.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define EOPNOTSUPP
Operation not supported on socket.
#define ENOMEM
Not enough space.
#define EIO
Input/output error.
#define EBUSY
Device or resource busy.
#define ENODEV
No such device.
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
#define le32_to_cpu(value)
#define cpu_to_le32(value)
Universal Serial Bus (USB)
#define USB_BULK_OUT
Bulk OUT endpoint (internal) type.
#define USB_DIR_IN
Data transfer is from device to host.
static void usb_endpoint_init(struct usb_endpoint *ep, struct usb_device *usb, struct usb_endpoint_driver_operations *driver)
Initialise USB endpoint.
#define __usb_driver
Declare a USB driver.
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
#define USB_BULK_IN
Bulk IN endpoint (internal) type.
#define USB_ID(_vendor, _product, _name, _description, _data)
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
@ USB_SCORE_NORMAL
Normal driver.
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
void intf_close(struct interface *intf, int rc)
Close an object interface.
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
#define iob_put(iobuf, len)
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define iob_pull(iobuf, len)
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define list_del(list)
Delete an entry from a list.
#define LIST_HEAD(list)
Declare a static list head.
void * zalloc(size_t size)
Allocate cleared memory.
Data transfer interface opening.
#define __uri_opener
Register a URI opener.
void process_del(struct process *process)
Remove process from process list.
void process_add(struct process *process)
Add process to process list.
static int process_running(struct process *process)
Check if process is running.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
#define ref_put(refcnt)
Drop reference to object.
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
#define container_of(ptr, type, field)
Get containing structure.
char * strerror(int errno)
Retrieve string representation of error number.
int strcmp(const char *first, const char *second)
Compare strings.
This protocol can be used on any device handle to obtain generic path/location information concerning...
An object interface descriptor.
An object interface operation.
void * data
Start of data.
A SCSI command information unit.
size_t data_out_len
Data-out buffer length.
size_t data_in_len
Data-in buffer length.
A Uniform Resource Identifier.
const char * opaque
Opaque part.
A USB configuration descriptor.
USB endpoint driver operations.
size_t mtu
Maximum transfer size.
unsigned int fill
Buffer fill level.
int open
Endpoint is open.
struct usb_device * usb
USB device.
uint8_t interface[0]
List of interface numbers.
A USB interface descriptor.
uint8_t cblen
Command block length.
uint32_t len
Data transfer length.
uint8_t cb[16]
Command block.
uint32_t signature
Signature.
A USB mass storage command.
A USB mass storage device.
struct usb_endpoint in
Bulk IN endpoint.
struct process process
Command process.
struct usb_endpoint out
Bulk OUT endpoint.
struct refcnt refcnt
Reference count.
int opened
Device opened flag.
struct usb_function * func
USB function.
struct list_head list
List of devices.
struct usbblk_command cmd
Current command (if any)
struct interface scsi
SCSI command-issuing interface.
struct interface data
SCSI data interface.
Uniform Resource Identifiers.
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
int usb_endpoint_clear_halt(struct usb_endpoint *ep)
Clear endpoint halt (if applicable)
int usb_endpoint_described(struct usb_endpoint *ep, struct usb_configuration_descriptor *config, struct usb_interface_descriptor *interface, unsigned int type, unsigned int index)
Describe USB endpoint from device configuration.
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
int usb_refill_limit(struct usb_endpoint *ep, unsigned int max)
Refill endpoint up to specified limit.
struct usb_interface_descriptor * usb_interface_descriptor(struct usb_configuration_descriptor *config, unsigned int interface, unsigned int alternate)
Locate USB interface descriptor.
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
static int usbblk_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
static void usbblk_stop(struct usbblk_device *usbblk, int rc)
Stop SCSI command.
static int usbblk_scsi_command(struct usbblk_device *usbblk, struct interface *data, struct scsi_cmd *scsicmd)
Issue SCSI command.
static int usbblk_open(struct usbblk_device *usbblk)
Open endpoints.
static uint16_t usbblk_tag
Next command tag.
static void usbblk_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
static struct interface_operation usbblk_data_operations[]
SCSI data interface operations.
static void usbblk_step(struct usbblk_device *usbblk)
Refill endpoints.
static int usbblk_in_refill(struct usbblk_device *usbblk)
Refill bulk IN endpoint.
static int usbblk_in_status(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN status.
static struct usb_device_id usbblk_ids[]
Mass storage class device IDs.
static struct interface_descriptor usbblk_scsi_desc
SCSI command interface descriptor.
static void usbblk_remove(struct usb_function *func)
Remove device.
static int usbblk_open_uri(struct interface *parent, struct uri *uri)
Open USB block device URI.
static struct usb_endpoint_driver_operations usbblk_in_operations
Bulk IN endpoint operations.
static size_t usbblk_scsi_window(struct usbblk_device *usbblk)
Check SCSI command flow-control window.
static void usbblk_scsi_close(struct usbblk_device *usbblk, int rc)
Close SCSI interface.
static void usbblk_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
static int usbblk_out_data(struct usbblk_device *usbblk)
Send bulk OUT data block.
static int usbblk_start(struct usbblk_device *usbblk, struct scsi_cmd *scsicmd)
Start new SCSI command.
static EFI_DEVICE_PATH_PROTOCOL * usbblk_efi_describe(struct usbblk_device *usbblk)
Describe as an EFI device path.
static int usbblk_out_command(struct usbblk_device *usbblk)
Issue bulk OUT command.
static int usbblk_out_refill(struct usbblk_device *usbblk)
Refill bulk OUT endpoint.
static struct usb_endpoint_driver_operations usbblk_out_operations
Bulk OUT endpoint operations.
static void usbblk_close(struct usbblk_device *usbblk)
Close endpoints.
static struct process_descriptor usbblk_process_desc
Refill process descriptor.
static struct interface_descriptor usbblk_data_desc
SCSI data interface descriptor.
static struct interface_operation usbblk_scsi_operations[]
SCSI command interface operations.
static int usbblk_in_data(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN data block.
static struct usbblk_device * usbblk_find(const char *name)
Find USB block device.
#define USBBLK_COMMAND_SIGNATURE
Command block wrapper signature.
#define USBBLK_STATUS_SIGNATURE
Command status wrapper signature.
#define USBBLK_MAX_LEN
Maximum length of USB data block.
#define USBBLK_RESET
Mass storage reset command.
#define USBBLK_MAX_FILL
Maximum endpoint fill level.
#define USB_PROTOCOL_MSC_BULK
Bulk-only transport protocol.
#define USB_CLASS_MSC
Mass storage class code.
#define USB_SUBCLASS_MSC_SCSI
SCSI command set subclass code.
#define USBBLK_TAG_MAGIC
Command tag magic.
size_t xfer_window(struct interface *intf)
Check flow control window.
Data transfer interfaces.