63 unsigned int interface = usbblk->func->
interface[0];
73 DBGC ( usbblk,
"USBBLK %s could not issue reset: %s\n",
80 DBGC ( usbblk,
"USBBLK %s could not open bulk OUT: %s\n",
87 DBGC ( usbblk,
"USBBLK %s could not reset bulk OUT: %s\n",
94 DBGC ( usbblk,
"USBBLK %s could not open bulk IN: %s\n",
101 DBGC ( usbblk,
"USBBLK %s could not reset bulk IN: %s\n",
155 assert ( ! (
cmd->scsi.data_in_len &&
cmd->scsi.data_out_len ) );
158 iobuf =
alloc_iob (
sizeof ( *wrapper ) );
165 wrapper =
iob_put ( iobuf,
sizeof ( *wrapper ) );
166 memset ( wrapper, 0,
sizeof ( *wrapper ) );
169 if (
cmd->scsi.data_out_len ) {
176 wrapper->
cblen =
sizeof ( wrapper->
cb );
177 memcpy ( wrapper->
cb, &
cmd->scsi.cdb, sizeof ( wrapper->
cb ) );
181 DBGC ( usbblk,
"USBBLK %s bulk OUT could not issue command: " 210 len = (
cmd->scsi.data_out_len -
cmd->offset );
228 DBGC ( usbblk,
"USBBLK %s bulk OUT could not send data: %s\n",
258 while ( (
cmd->offset <
cmd->scsi.data_out_len ) &&
289 DBGC ( usbblk,
"USBBLK %s bulk OUT failed: %s\n",
295 if (
cmd->offset <
cmd->scsi.data_out_len )
363 if (
len <
sizeof ( *stat ) ) {
364 DBGC ( usbblk,
"USBBLK %s bulk IN malformed status:\n",
373 DBGC ( usbblk,
"USBBLK %s bulk IN invalid signature %08x:\n",
375 DBGC_HDA ( usbblk, 0, stat,
sizeof ( *stat ) );
380 if ( stat->
tag !=
cmd->tag ) {
381 DBGC ( usbblk,
"USBBLK %s bulk IN tag mismatch (got %08x, " 384 DBGC_HDA ( usbblk, 0, stat,
sizeof ( *stat ) );
390 DBGC ( usbblk,
"USBBLK %s bulk IN status %02x:\n",
392 DBGC_HDA ( usbblk, 0, stat,
sizeof ( *stat ) );
398 DBGC ( usbblk,
"USBBLK %s bulk IN residue %#x:\n",
426 remaining =
sizeof ( *stat );
427 if (
cmd->scsi.data_in_len ) {
429 remaining += (
cmd->scsi.data_in_len -
cmd->offset );
464 DBGC ( usbblk,
"USBBLK %s bulk IN failed: %s\n",
473 if (
cmd->scsi.data_in_len ) {
475 remaining = (
cmd->scsi.data_in_len -
cmd->offset );
477 if (
len > remaining )
562 DBGC ( usbblk,
"USBBLK %s closing for error recovery\n",
586 DBGC ( usbblk,
"USBBLK %s cannot support multiple commands\n",
594 DBGC ( usbblk,
"USBBLK %s cannot support bidirectional " 596 goto err_bidirectional;
649 return (
cmd->tag ? 0 : 1 );
783 DBGC ( usbblk,
"USBBLK %s could not open SCSI device: %s\n",
822 usbblk =
zalloc (
sizeof ( *usbblk ) );
839 DBGC ( usbblk,
"USBBLK %s missing interface descriptor\n",
848 DBGC ( usbblk,
"USBBLK %s could not describe bulk OUT: %s\n",
854 DBGC ( usbblk,
"USBBLK %s could not describe bulk IN: %s\n",
#define iob_pull(iobuf, len)
#define EINVAL
Invalid argument.
An object interface operation.
struct usb_endpoint out
Bulk OUT endpoint.
struct arbelprm_rc_send_wqe rc
struct usbblk_command cmd
Current command (if any)
void intf_close(struct interface *intf, int rc)
Close an object interface.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
#define USBBLK_MAX_FILL
Maximum endpoint fill level.
struct process process
Command process.
A USB mass storage command.
#define iob_put(iobuf, len)
static int usbblk_in_data(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN data block.
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
size_t data_out_len
Data-out buffer length.
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
#define EBUSY
Device or resource busy.
uint8_t interface[0]
List of interface numbers.
uint8_t cb[16]
Command block.
#define le32_to_cpu(value)
static int usbblk_start(struct usbblk_device *usbblk, struct scsi_cmd *scsicmd)
Start new SCSI command.
int usb_refill_limit(struct usb_endpoint *ep, unsigned int max)
Refill endpoint up to specified limit.
static int usbblk_out_data(struct usbblk_device *usbblk)
Send bulk OUT data block.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
#define USB_PROTOCOL_MSC_BULK
Bulk-only transport protocol.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
uint8_t cblen
Command block length.
uint64_t desc
Microcode descriptor list physical address.
size_t data_in_len
Data-in buffer length.
static struct usb_endpoint_driver_operations usbblk_in_operations
Bulk IN endpoint operations.
#define ENOENT
No such file or directory.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
int usb_endpoint_clear_halt(struct usb_endpoint *ep)
Clear endpoint halt (if applicable)
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
static int usbblk_open_uri(struct interface *parent, struct uri *uri)
Open USB block device URI.
static int usbblk_in_refill(struct usbblk_device *usbblk)
Refill bulk IN endpoint.
struct usb_driver usbblk_driver __usb_driver
Mass storage driver.
This protocol can be used on any device handle to obtain generic path/location information concerning...
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Uniform Resource Identifiers.
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
int open
Endpoint is open.
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.
void process_del(struct process *process)
Remove process from process list.
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
uint32_t signature
Signature.
size_t xfer_window(struct interface *intf)
Check flow control window.
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
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.
Data transfer interfaces.
static void usbblk_stop(struct usbblk_device *usbblk, int rc)
Stop SCSI command.
static void usbblk_scsi_close(struct usbblk_device *usbblk, int rc)
Close SCSI interface.
#define list_del(list)
Delete an entry from a list.
static uint16_t usbblk_tag
Next command tag.
#define ENOMEM
Not enough space.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
A USB interface descriptor.
struct refcnt refcnt
Reference count.
struct interface scsi
SCSI command-issuing interface.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
#define USBBLK_RESET
Mass storage reset command.
#define USB_BULK_OUT
Bulk OUT endpoint (internal) type.
A USB mass storage device.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
static int usbblk_scsi_command(struct usbblk_device *usbblk, struct interface *data, struct scsi_cmd *scsicmd)
Issue SCSI command.
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
const char * scheme
URI protocol name.
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
struct list_head list
List of devices.
#define USB_DIR_IN
Data transfer is from device to host.
uint8_t lun
Logical Unit Number.
#define cpu_to_le32(value)
struct usb_interface_descriptor * usb_interface_descriptor(struct usb_configuration_descriptor *config, unsigned int interface, unsigned int alternate)
Locate USB interface descriptor.
void process_add(struct process *process)
Add process to process list.
static int usbblk_open(struct usbblk_device *usbblk)
Open endpoints.
An object interface descriptor.
char * strerror(int errno)
Retrieve string representation of error number.
#define USBBLK_COMMAND_SIGNATURE
Command block wrapper signature.
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
void * zalloc(size_t size)
Allocate cleared memory.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define USBBLK_MAX_LEN
Maximum length of USB data block.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
#define EOPNOTSUPP
Operation not supported on socket.
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
#define USBBLK_STATUS_SIGNATURE
Command status wrapper signature.
#define ENODEV
No such device.
Data transfer interface opening.
uint32_t residue
Data residue.
static int usbblk_out_refill(struct usbblk_device *usbblk)
Refill bulk OUT endpoint.
unsigned int fill
Buffer fill level.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
struct usb_device * usb
USB device.
static void usb_endpoint_init(struct usb_endpoint *ep, struct usb_device *usb, struct usb_endpoint_driver_operations *driver)
Initialise USB endpoint.
static void usbblk_remove(struct usb_function *func)
Remove device.
#define USB_SUBCLASS_MSC_SCSI
SCSI command set subclass code.
struct usb_endpoint in
Bulk IN endpoint.
size_t mtu
Maximum transfer size.
static int process_running(struct process *process)
Check if process is running.
static struct interface_descriptor usbblk_data_desc
SCSI data interface descriptor.
#define USB_BULK_IN
Bulk IN endpoint (internal) type.
struct usb_function * func
USB function.
static size_t usbblk_scsi_window(struct usbblk_device *usbblk)
Check SCSI command flow-control window.
A SCSI command information unit.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
A USB configuration descriptor.
#define USBBLK_TAG_MAGIC
Command tag magic.
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
#define UNULL
Equivalent of NULL for user pointers.
static int usbblk_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
const char * opaque
Opaque part.
static struct interface_descriptor usbblk_scsi_desc
SCSI command interface descriptor.
#define USB_ANY_ID
Match-anything ID.
int strcmp(const char *first, const char *second)
Compare strings.
Universal Serial Bus (USB)
static struct interface_operation usbblk_scsi_operations[]
SCSI command interface operations.
void * data
Start of data.
static int usbblk_in_status(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN status.
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
#define EIO
Input/output error.
static struct interface_operation usbblk_data_operations[]
SCSI data interface operations.
static struct usbblk_device * usbblk_find(const char *name)
Find USB block device.
uint8_t data[48]
Additional event data.
int opened
Device opened flag.
A Uniform Resource Identifier.
static LIST_HEAD(usbblk_devices)
List of USB block devices.
struct uri_opener usbblk_uri_opener __uri_opener
USB block device URI opener.
static void usbblk_step(struct usbblk_device *usbblk)
Refill endpoints.
#define USB_CLASS_MSC
Mass storage class code.
static void usbblk_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
uint32_t signature
Signature.
USB endpoint driver operations.
static void usbblk_close(struct usbblk_device *usbblk)
Close endpoints.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
static EFI_DEVICE_PATH_PROTOCOL * usbblk_efi_describe(struct usbblk_device *usbblk)
Describe as an EFI device path.
uint32_t len
Data transfer length.
#define NULL
NULL pointer (VOID *)
static struct process_descriptor usbblk_process_desc
Refill process descriptor.
static struct usb_endpoint_driver_operations usbblk_out_operations
Bulk OUT endpoint operations.
static struct usb_device_id usbblk_ids[]
Mass storage class device IDs.
#define ref_put(refcnt)
Drop reference to object.
struct interface data
SCSI data interface.
struct usb_device_id * ids
USB ID table.
static int usbblk_out_command(struct usbblk_device *usbblk)
Issue bulk OUT command.
void * memset(void *dest, int character, size_t len) __nonnull
static void usbblk_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.