iPXE
usbblk.c File Reference

USB mass storage driver. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/usb.h>
#include <ipxe/scsi.h>
#include <ipxe/xfer.h>
#include <ipxe/uri.h>
#include <ipxe/open.h>
#include <ipxe/efi/efi_path.h>
#include "usbblk.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void usbblk_stop (struct usbblk_device *usbblk, int rc)
 Stop SCSI command.
static LIST_HEAD (usbblk_devices)
 List of USB block devices.
static int usbblk_open (struct usbblk_device *usbblk)
 Open endpoints.
static void usbblk_close (struct usbblk_device *usbblk)
 Close endpoints.
static int usbblk_out_command (struct usbblk_device *usbblk)
 Issue bulk OUT command.
static int usbblk_out_data (struct usbblk_device *usbblk)
 Send bulk OUT data block.
static int usbblk_out_refill (struct usbblk_device *usbblk)
 Refill bulk OUT endpoint.
static void usbblk_out_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk OUT transfer.
static int usbblk_in_data (struct usbblk_device *usbblk, const void *data, size_t len)
 Handle bulk IN data block.
static int usbblk_in_status (struct usbblk_device *usbblk, const void *data, size_t len)
 Handle bulk IN status.
static int usbblk_in_refill (struct usbblk_device *usbblk)
 Refill bulk IN endpoint.
static void usbblk_in_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk IN transfer.
static void usbblk_step (struct usbblk_device *usbblk)
 Refill endpoints.
static int usbblk_start (struct usbblk_device *usbblk, struct scsi_cmd *scsicmd)
 Start new SCSI command.
static size_t usbblk_scsi_window (struct usbblk_device *usbblk)
 Check SCSI command flow-control window.
static int usbblk_scsi_command (struct usbblk_device *usbblk, struct interface *data, struct scsi_cmd *scsicmd)
 Issue SCSI command.
static void usbblk_scsi_close (struct usbblk_device *usbblk, int rc)
 Close SCSI interface.
static EFI_DEVICE_PATH_PROTOCOLusbblk_efi_describe (struct usbblk_device *usbblk)
 Describe as an EFI device path.
static struct usbblk_deviceusbblk_find (const char *name)
 Find USB block device.
static int usbblk_open_uri (struct interface *parent, struct uri *uri)
 Open USB block device URI.
static int usbblk_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe device.
static void usbblk_remove (struct usb_function *func)
 Remove device.

Variables

static struct usb_endpoint_driver_operations usbblk_out_operations
 Bulk OUT endpoint operations.
static struct usb_endpoint_driver_operations usbblk_in_operations
 Bulk IN endpoint operations.
static struct process_descriptor usbblk_process_desc
 Refill process descriptor.
static uint16_t usbblk_tag
 Next command tag.
static struct interface_operation usbblk_data_operations []
 SCSI data interface operations.
static struct interface_descriptor usbblk_data_desc
 SCSI data interface descriptor.
static struct interface_operation usbblk_scsi_operations []
 SCSI command interface operations.
static struct interface_descriptor usbblk_scsi_desc
 SCSI command interface descriptor.
struct uri_opener usbblk_uri_opener __uri_opener
 USB block device URI opener.
static struct usb_device_id usbblk_ids []
 Mass storage class device IDs.
struct usb_driver usbblk_driver __usb_driver
 Mass storage driver.

Detailed Description

USB mass storage driver.

Definition in file usbblk.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

References rc.

◆ usbblk_stop()

void usbblk_stop ( struct usbblk_device * usbblk,
int rc )
static

Stop SCSI command.

Parameters
usbblkUSB block device
rcReason for stop

Definition at line 559 of file usbblk.c.

559 {
560
561 /* Stop process */
562 process_del ( &usbblk->process );
563
564 /* Reset command */
565 memset ( &usbblk->cmd, 0, sizeof ( usbblk->cmd ) );
566
567 /* Close endpoints if an error occurred */
568 if ( rc != 0 ) {
569 DBGC ( usbblk, "USBBLK %s closing for error recovery\n",
570 usbblk->func->name );
571 usbblk_close ( usbblk );
572 }
573
574 /* Terminate command */
575 intf_restart ( &usbblk->data, rc );
576}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:530
void * memset(void *dest, int character, size_t len) __nonnull
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
const char * name
Name.
Definition usb.h:686
struct process process
Command process.
Definition usbblk.h:96
struct usb_function * func
USB function.
Definition usbblk.h:85
struct usbblk_command cmd
Current command (if any).
Definition usbblk.h:101
struct interface data
SCSI data interface.
Definition usbblk.h:94
static void usbblk_close(struct usbblk_device *usbblk)
Close endpoints.
Definition usbblk.c:125

References usbblk_device::cmd, usbblk_device::data, DBGC, usbblk_device::func, intf_restart(), memset(), usb_function::name, usbblk_device::process, process_del(), rc, and usbblk_close().

Referenced by usbblk_in_complete(), usbblk_in_status(), usbblk_out_complete(), usbblk_scsi_close(), and usbblk_scsi_command().

◆ LIST_HEAD()

LIST_HEAD ( usbblk_devices )
static

List of USB block devices.

◆ usbblk_open()

int usbblk_open ( struct usbblk_device * usbblk)
static

Open endpoints.

Parameters
usbblkUSB block device
Return values
rcReturn status code

Definition at line 63 of file usbblk.c.

63 {
64 struct usb_device *usb = usbblk->func->usb;
65 unsigned int interface = usbblk->func->interface[0];
66 int rc;
67
68 /* Sanity checks */
69 assert ( ! usbblk->in.open );
70 assert ( ! usbblk->out.open );
71
72 /* Issue reset */
73 if ( ( rc = usb_control ( usb, USBBLK_RESET, 0, interface,
74 NULL, 0 ) ) != 0 ) {
75 DBGC ( usbblk, "USBBLK %s could not issue reset: %s\n",
76 usbblk->func->name, strerror ( rc ) );
77 goto err_reset;
78 }
79
80 /* Open bulk OUT endpoint */
81 if ( ( rc = usb_endpoint_open ( &usbblk->out ) ) != 0 ) {
82 DBGC ( usbblk, "USBBLK %s could not open bulk OUT: %s\n",
83 usbblk->func->name, strerror ( rc ) );
84 goto err_open_out;
85 }
86
87 /* Clear any bulk OUT halt condition */
88 if ( ( rc = usb_endpoint_clear_halt ( &usbblk->out ) ) != 0 ) {
89 DBGC ( usbblk, "USBBLK %s could not reset bulk OUT: %s\n",
90 usbblk->func->name, strerror ( rc ) );
91 goto err_clear_out;
92 }
93
94 /* Open bulk IN endpoint */
95 if ( ( rc = usb_endpoint_open ( &usbblk->in ) ) != 0 ) {
96 DBGC ( usbblk, "USBBLK %s could not open bulk IN: %s\n",
97 usbblk->func->name, strerror ( rc ) );
98 goto err_open_in;
99 }
100
101 /* Clear any bulk IN halt condition */
102 if ( ( rc = usb_endpoint_clear_halt ( &usbblk->in ) ) != 0 ) {
103 DBGC ( usbblk, "USBBLK %s could not reset bulk IN: %s\n",
104 usbblk->func->name, strerror ( rc ) );
105 goto err_clear_in;
106 }
107
108 return 0;
109
110 err_clear_in:
111 usb_endpoint_close ( &usbblk->in );
112 err_open_in:
113 err_clear_out:
114 usb_endpoint_close ( &usbblk->out );
115 err_open_out:
116 err_reset:
117 return rc;
118}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An object interface.
Definition interface.h:125
A USB device.
Definition usb.h:733
int open
Endpoint is open.
Definition usb.h:429
struct usb_device * usb
USB device.
Definition usb.h:688
struct usb_endpoint in
Bulk IN endpoint.
Definition usbblk.h:89
struct usb_endpoint out
Bulk OUT endpoint.
Definition usbblk.h:87
int usb_endpoint_open(struct usb_endpoint *ep)
Open USB endpoint.
Definition usb.c:293
void usb_endpoint_close(struct usb_endpoint *ep)
Close USB endpoint.
Definition usb.c:399
int usb_endpoint_clear_halt(struct usb_endpoint *ep)
Clear endpoint halt (if applicable).
Definition usb.c:371
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.
Definition usb.c:783
#define USBBLK_RESET
Mass storage reset command.
Definition usbblk.h:28

References assert, DBGC, usbblk_device::func, usbblk_device::in, usb_function::name, NULL, usb_endpoint::open, usbblk_device::out, rc, strerror(), usb_function::usb, usb_control(), usb_endpoint_clear_halt(), usb_endpoint_close(), usb_endpoint_open(), and USBBLK_RESET.

Referenced by usbblk_scsi_command().

◆ usbblk_close()

void usbblk_close ( struct usbblk_device * usbblk)
static

Close endpoints.

Parameters
usbblkUSB block device

Definition at line 125 of file usbblk.c.

125 {
126
127 /* Close bulk OUT endpoint */
128 if ( usbblk->out.open )
129 usb_endpoint_close ( &usbblk->out );
130
131 /* Close bulk IN endpoint */
132 if ( usbblk->in.open )
133 usb_endpoint_close ( &usbblk->in );
134}

References usbblk_device::in, usb_endpoint::open, usbblk_device::out, and usb_endpoint_close().

Referenced by usbblk_scsi_close(), usbblk_scsi_command(), and usbblk_stop().

◆ usbblk_out_command()

int usbblk_out_command ( struct usbblk_device * usbblk)
static

Issue bulk OUT command.

Parameters
usbblkUSB block device
Return values
rcReturn status code

Definition at line 149 of file usbblk.c.

149 {
150 struct usbblk_command *cmd = &usbblk->cmd;
151 struct usbblk_command_wrapper *wrapper;
152 struct io_buffer *iobuf;
153 int rc;
154
155 /* Sanity checks */
156 assert ( cmd->tag );
157 assert ( ! ( cmd->scsi.data_in.len && cmd->scsi.data_out.len ) );
158
159 /* Allocate I/O buffer */
160 iobuf = alloc_iob ( sizeof ( *wrapper ) );
161 if ( ! iobuf ) {
162 rc = -ENOMEM;
163 goto err_alloc;
164 }
165
166 /* Populate command */
167 wrapper = iob_put ( iobuf, sizeof ( *wrapper ) );
168 memset ( wrapper, 0, sizeof ( *wrapper ) );
170 wrapper->tag = cmd->tag; /* non-endian */
171 if ( cmd->scsi.data_out.len ) {
172 wrapper->len = cpu_to_le32 ( cmd->scsi.data_out.len );
173 } else {
174 wrapper->len = cpu_to_le32 ( cmd->scsi.data_in.len );
175 wrapper->flags = USB_DIR_IN;
176 }
177 wrapper->lun = ntohs ( cmd->scsi.lun.u16[0] );
178 wrapper->cblen = sizeof ( wrapper->cb );
179 memcpy ( wrapper->cb, &cmd->scsi.cdb, sizeof ( wrapper->cb ) );
180
181 /* Issue command */
182 if ( ( rc = usb_stream ( &usbblk->out, iobuf, 0 ) ) != 0 ) {
183 DBGC ( usbblk, "USBBLK %s bulk OUT could not issue command: "
184 "%s\n", usbblk->func->name, strerror ( rc ) );
185 goto err_stream;
186 }
187
188 return 0;
189
190 err_stream:
191 free_iob ( iobuf );
192 err_alloc:
193 return rc;
194}
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
#define ENOMEM
Not enough space.
Definition errno.h:578
#define cpu_to_le32(value)
Definition byteswap.h:108
#define ntohs(value)
Definition byteswap.h:137
#define USB_DIR_IN
Data transfer is from device to host.
Definition usb.h:98
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:185
A persistent I/O buffer.
Definition iobuf.h:98
Command block wrapper.
Definition usbblk.h:32
uint8_t lun
LUN.
Definition usbblk.h:42
uint8_t flags
Flags.
Definition usbblk.h:40
uint8_t cblen
Command block length.
Definition usbblk.h:44
uint32_t len
Data transfer length.
Definition usbblk.h:38
uint32_t tag
Tag.
Definition usbblk.h:36
uint8_t cb[16]
Command block.
Definition usbblk.h:46
uint32_t signature
Signature.
Definition usbblk.h:34
A USB mass storage command.
Definition usbblk.h:68
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:545
#define USBBLK_COMMAND_SIGNATURE
Command block wrapper signature.
Definition usbblk.h:50

References alloc_iob(), assert, usbblk_command_wrapper::cb, usbblk_command_wrapper::cblen, cmd, usbblk_device::cmd, cpu_to_le32, DBGC, ENOMEM, usbblk_command_wrapper::flags, free_iob(), usbblk_device::func, iob_put, usbblk_command_wrapper::len, usbblk_command_wrapper::lun, memcpy(), memset(), usb_function::name, ntohs, usbblk_device::out, rc, usbblk_command_wrapper::signature, strerror(), usbblk_command_wrapper::tag, USB_DIR_IN, usb_stream(), and USBBLK_COMMAND_SIGNATURE.

Referenced by usbblk_start().

◆ usbblk_out_data()

int usbblk_out_data ( struct usbblk_device * usbblk)
static

Send bulk OUT data block.

Parameters
usbblkUSB block device
Return values
rcReturn status code

Definition at line 202 of file usbblk.c.

202 {
203 struct usbblk_command *cmd = &usbblk->cmd;
204 struct io_buffer *iobuf;
205 size_t len;
206 int rc;
207
208 /* Calculate length */
209 assert ( cmd->tag );
210 assert ( cmd->scsi.data_out.len != 0 );
211 assert ( cmd->offset < cmd->scsi.data_out.len );
212 len = ( cmd->scsi.data_out.len - cmd->offset );
213 if ( len > USBBLK_MAX_LEN )
215 assert ( ( len % usbblk->out.mtu ) == 0 );
216
217 /* Allocate I/O buffer */
218 iobuf = alloc_iob ( len );
219 if ( ! iobuf ) {
220 rc = -ENOMEM;
221 goto err_alloc;
222 }
223
224 /* Populate I/O buffer */
225 if ( ( rc = xferbuf_read ( &cmd->scsi.data_out, cmd->offset,
226 iob_put ( iobuf, len ), len ) ) != 0 )
227 goto err_read;
228
229 /* Send data */
230 if ( ( rc = usb_stream ( &usbblk->out, iobuf, 0 ) ) != 0 ) {
231 DBGC ( usbblk, "USBBLK %s bulk OUT could not send data: %s\n",
232 usbblk->func->name, strerror ( rc ) );
233 goto err_stream;
234 }
235
236 /* Consume data */
237 cmd->offset += len;
238
239 return 0;
240
241 err_stream:
242 err_read:
243 free_iob ( iobuf );
244 err_alloc:
245 return rc;
246}
ring len
Length.
Definition dwmac.h:226
size_t mtu
Maximum transfer size.
Definition usb.h:422
#define USBBLK_MAX_LEN
Maximum length of USB data block.
Definition usbblk.h:114
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition xferbuf.c:166

References alloc_iob(), assert, cmd, usbblk_device::cmd, DBGC, ENOMEM, free_iob(), usbblk_device::func, iob_put, len, usb_endpoint::mtu, usb_function::name, usbblk_device::out, rc, strerror(), usb_stream(), USBBLK_MAX_LEN, and xferbuf_read().

Referenced by usbblk_out_refill().

◆ usbblk_out_refill()

int usbblk_out_refill ( struct usbblk_device * usbblk)
static

Refill bulk OUT endpoint.

Parameters
usbblkUSB block device
Return values
rcReturn status code

Definition at line 254 of file usbblk.c.

254 {
255 struct usbblk_command *cmd = &usbblk->cmd;
256 int rc;
257
258 /* Sanity checks */
259 assert ( cmd->tag );
260
261 /* Refill endpoint */
262 while ( ( cmd->offset < cmd->scsi.data_out.len ) &&
263 ( usbblk->out.fill < USBBLK_MAX_FILL ) ) {
264 if ( ( rc = usbblk_out_data ( usbblk ) ) != 0 )
265 return rc;
266 }
267
268 return 0;
269}
unsigned int fill
Buffer fill level.
Definition usb.h:431
static int usbblk_out_data(struct usbblk_device *usbblk)
Send bulk OUT data block.
Definition usbblk.c:202
#define USBBLK_MAX_FILL
Maximum endpoint fill level.
Definition usbblk.h:120

References assert, cmd, usbblk_device::cmd, usb_endpoint::fill, usbblk_device::out, rc, USBBLK_MAX_FILL, and usbblk_out_data().

Referenced by usbblk_step().

◆ usbblk_out_complete()

void usbblk_out_complete ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int rc )
static

Complete bulk OUT transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 278 of file usbblk.c.

279 {
280 struct usbblk_device *usbblk =
281 container_of ( ep, struct usbblk_device, out );
282 struct usbblk_command *cmd = &usbblk->cmd;
283
284 /* Ignore cancellations after closing endpoint */
285 if ( ! ep->open )
286 goto drop;
287
288 /* Sanity check */
289 assert ( cmd->tag );
290
291 /* Check for failures */
292 if ( rc != 0 ) {
293 DBGC ( usbblk, "USBBLK %s bulk OUT failed: %s\n",
294 usbblk->func->name, strerror ( rc ) );
295 goto err;
296 }
297
298 /* Trigger refill process, if applicable */
299 if ( cmd->offset < cmd->scsi.data_out.len )
300 process_add ( &usbblk->process );
301
302 drop:
303 /* Free I/O buffer */
304 free_iob ( iobuf );
305
306 return;
307
308 err:
309 free_iob ( iobuf );
310 usbblk_stop ( usbblk, rc );
311}
__be32 out[4]
Definition CIB_PRM.h:8
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A USB mass storage device.
Definition usbblk.h:78
static void usbblk_stop(struct usbblk_device *usbblk, int rc)
Stop SCSI command.
Definition usbblk.c:559

References assert, cmd, usbblk_device::cmd, container_of, DBGC, free_iob(), usbblk_device::func, usb_function::name, usb_endpoint::open, out, usbblk_device::process, process_add(), rc, strerror(), and usbblk_stop().

◆ usbblk_in_data()

int usbblk_in_data ( struct usbblk_device * usbblk,
const void * data,
size_t len )
static

Handle bulk IN data block.

Parameters
usbblkUSB block device
dataData block
lenLength of data
Return values
rcReturn status code

Definition at line 333 of file usbblk.c.

334 {
335 struct usbblk_command *cmd = &usbblk->cmd;
336 int rc;
337
338 /* Sanity checks */
339 assert ( cmd->tag );
340 assert ( cmd->scsi.data_in.len != 0 );
341 assert ( cmd->offset <= cmd->scsi.data_in.len );
342 assert ( len <= ( cmd->scsi.data_in.len - cmd->offset ) );
343
344 /* Store data */
345 if ( ( rc = xferbuf_write ( &cmd->scsi.data_in, cmd->offset,
346 data, len ) ) != 0 )
347 return rc;
348 cmd->offset += len;
349
350 return 0;
351}
uint8_t data[48]
Additional event data.
Definition ena.h:11
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:133

References assert, cmd, usbblk_device::cmd, data, len, rc, and xferbuf_write().

Referenced by usbblk_in_complete().

◆ usbblk_in_status()

int usbblk_in_status ( struct usbblk_device * usbblk,
const void * data,
size_t len )
static

Handle bulk IN status.

Parameters
usbblkUSB block device
dataStatus data
lenLength of status data
Return values
rcReturn status code

Definition at line 361 of file usbblk.c.

362 {
363 struct usbblk_command *cmd = &usbblk->cmd;
364 const struct usbblk_status_wrapper *stat;
365
366 /* Sanity checks */
367 assert ( cmd->tag );
368
369 /* Validate length */
370 if ( len < sizeof ( *stat ) ) {
371 DBGC ( usbblk, "USBBLK %s bulk IN malformed status:\n",
372 usbblk->func->name );
373 DBGC_HDA ( usbblk, 0, data, len );
374 return -EIO;
375 }
376 stat = data;
377
378 /* Validate signature */
379 if ( stat->signature != cpu_to_le32 ( USBBLK_STATUS_SIGNATURE ) ) {
380 DBGC ( usbblk, "USBBLK %s bulk IN invalid signature %08x:\n",
381 usbblk->func->name, le32_to_cpu ( stat->signature ) );
382 DBGC_HDA ( usbblk, 0, stat, sizeof ( *stat ) );
383 return -EIO;
384 }
385
386 /* Validate tag */
387 if ( stat->tag != cmd->tag ) {
388 DBGC ( usbblk, "USBBLK %s bulk IN tag mismatch (got %08x, "
389 "expected %08x):\n",
390 usbblk->func->name, stat->tag, cmd->tag );
391 DBGC_HDA ( usbblk, 0, stat, sizeof ( *stat ) );
392 return -EIO;
393 }
394
395 /* Check status */
396 if ( stat->status ) {
397 DBGC ( usbblk, "USBBLK %s bulk IN status %02x:\n",
398 usbblk->func->name, stat->status );
399 DBGC_HDA ( usbblk, 0, stat, sizeof ( *stat ) );
400 return -EIO;
401 }
402
403 /* Check for residual data */
404 if ( stat->residue ) {
405 DBGC ( usbblk, "USBBLK %s bulk IN residue %#x:\n",
406 usbblk->func->name, le32_to_cpu ( stat->residue ) );
407 return -EIO;
408 }
409
410 /* Mark command as complete */
411 usbblk_stop ( usbblk, 0 );
412
413 return 0;
414}
uint32_t stat
Completion status.
Definition dwmac.h:1
#define DBGC_HDA(...)
Definition compiler.h:531
#define EIO
Input/output error.
Definition errno.h:477
#define le32_to_cpu(value)
Definition byteswap.h:114
Command status wrapper.
Definition usbblk.h:53
#define USBBLK_STATUS_SIGNATURE
Command status wrapper signature.
Definition usbblk.h:65

References assert, cmd, usbblk_device::cmd, cpu_to_le32, data, DBGC, DBGC_HDA, EIO, usbblk_device::func, le32_to_cpu, len, usb_function::name, stat, USBBLK_STATUS_SIGNATURE, and usbblk_stop().

Referenced by usbblk_in_complete().

◆ usbblk_in_refill()

int usbblk_in_refill ( struct usbblk_device * usbblk)
static

Refill bulk IN endpoint.

Parameters
usbblkUSB block device
Return values
rcReturn status code

Definition at line 422 of file usbblk.c.

422 {
423 struct usbblk_command *cmd = &usbblk->cmd;
425 size_t remaining;
426 unsigned int max;
427 int rc;
428
429 /* Sanity checks */
430 assert ( cmd->tag );
431
432 /* Calculate maximum required refill */
433 remaining = sizeof ( *stat );
434 if ( cmd->scsi.data_in.len ) {
435 assert ( cmd->offset <= cmd->scsi.data_in.len );
436 remaining += ( cmd->scsi.data_in.len - cmd->offset );
437 }
438 max = ( ( remaining + USBBLK_MAX_LEN - 1 ) / USBBLK_MAX_LEN );
439
440 /* Refill bulk IN endpoint */
441 if ( ( rc = usb_refill_limit ( &usbblk->in, max ) ) != 0 )
442 return rc;
443
444 return 0;
445}
#define max(x, y)
Definition ath.h:41
int usb_refill_limit(struct usb_endpoint *ep, unsigned int max)
Refill endpoint up to specified limit.
Definition usb.c:660

References assert, cmd, usbblk_device::cmd, usbblk_device::in, max, rc, stat, usb_refill_limit(), and USBBLK_MAX_LEN.

Referenced by usbblk_step().

◆ usbblk_in_complete()

void usbblk_in_complete ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int rc )
static

Complete bulk IN transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 454 of file usbblk.c.

455 {
456 struct usbblk_device *usbblk =
457 container_of ( ep, struct usbblk_device, in );
458 struct usbblk_command *cmd = &usbblk->cmd;
459 size_t remaining;
460 size_t len;
461
462 /* Ignore cancellations after closing endpoint */
463 if ( ! ep->open )
464 goto drop;
465
466 /* Sanity check */
467 assert ( cmd->tag );
468
469 /* Handle errors */
470 if ( rc != 0 ) {
471 DBGC ( usbblk, "USBBLK %s bulk IN failed: %s\n",
472 usbblk->func->name, strerror ( rc ) );
473 goto err;
474 }
475
476 /* Trigger refill process */
477 process_add ( &usbblk->process );
478
479 /* Handle data portion, if any */
480 if ( cmd->scsi.data_in.len ) {
481 assert ( cmd->offset <= cmd->scsi.data_in.len );
482 remaining = ( cmd->scsi.data_in.len - cmd->offset );
483 len = iob_len ( iobuf );
484 if ( len > remaining )
485 len = remaining;
486 if ( len ) {
487 if ( ( rc = usbblk_in_data ( usbblk, iobuf->data,
488 len ) ) != 0 )
489 goto err;
490 iob_pull ( iobuf, len );
491 }
492 }
493
494 /* Handle status portion, if any */
495 len = iob_len ( iobuf );
496 if ( len ) {
497 if ( ( rc = usbblk_in_status ( usbblk, iobuf->data,
498 len ) ) != 0 )
499 goto err;
500 }
501
502 drop:
503 /* Free I/O buffer */
504 free_iob ( iobuf );
505
506 return;
507
508 err:
509 free_iob ( iobuf );
510 usbblk_stop ( usbblk, rc );
511}
__be32 in[4]
Definition CIB_PRM.h:7
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
void * data
Start of data.
Definition iobuf.h:113
static int usbblk_in_status(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN status.
Definition usbblk.c:361
static int usbblk_in_data(struct usbblk_device *usbblk, const void *data, size_t len)
Handle bulk IN data block.
Definition usbblk.c:333

References assert, cmd, usbblk_device::cmd, container_of, io_buffer::data, DBGC, free_iob(), usbblk_device::func, in, iob_len(), iob_pull, len, usb_function::name, usb_endpoint::open, usbblk_device::process, process_add(), rc, strerror(), usbblk_in_data(), usbblk_in_status(), and usbblk_stop().

◆ usbblk_step()

void usbblk_step ( struct usbblk_device * usbblk)
static

Refill endpoints.

Parameters
usbblkUSB block device

Definition at line 530 of file usbblk.c.

530 {
531
532 /* Refill bulk OUT endpoint */
533 usbblk_out_refill ( usbblk );
534
535 /* Refill bulk IN endpoint */
536 usbblk_in_refill ( usbblk );
537}
static int usbblk_in_refill(struct usbblk_device *usbblk)
Refill bulk IN endpoint.
Definition usbblk.c:422
static int usbblk_out_refill(struct usbblk_device *usbblk)
Refill bulk OUT endpoint.
Definition usbblk.c:254

References usbblk_in_refill(), and usbblk_out_refill().

◆ usbblk_start()

int usbblk_start ( struct usbblk_device * usbblk,
struct scsi_cmd * scsicmd )
static

Start new SCSI command.

Parameters
usbblkUSB block device
scsicmdSCSI command
Return values
rcReturn status code

Definition at line 585 of file usbblk.c.

586 {
587 struct usbblk_command *cmd = &usbblk->cmd;
588 int rc;
589
590 /* Fail if command is in progress */
591 if ( cmd->tag ) {
592 rc = -EBUSY;
593 DBGC ( usbblk, "USBBLK %s cannot support multiple commands\n",
594 usbblk->func->name );
595 goto err_busy;
596 }
597
598 /* Refuse bidirectional commands */
599 if ( scsicmd->data_in.len && scsicmd->data_out.len ) {
600 rc = -EOPNOTSUPP;
601 DBGC ( usbblk, "USBBLK %s cannot support bidirectional "
602 "commands\n", usbblk->func->name );
603 goto err_bidirectional;
604 }
605
606 /* Sanity checks */
607 assert ( ! process_running ( &usbblk->process ) );
608 assert ( cmd->offset == 0 );
609
610 /* Initialise command */
611 memcpy ( &cmd->scsi, scsicmd, sizeof ( cmd->scsi ) );
612 cmd->tag = ( USBBLK_TAG_MAGIC | ++usbblk_tag );
613
614 /* Issue bulk OUT command */
615 if ( ( rc = usbblk_out_command ( usbblk ) ) != 0 )
616 goto err_command;
617
618 /* Start refill process */
619 process_add ( &usbblk->process );
620
621 return 0;
622
623 err_command:
624 memset ( &usbblk->cmd, 0, sizeof ( usbblk->cmd ) );
625 err_bidirectional:
626 err_busy:
627 return rc;
628}
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:648
#define EBUSY
Device or resource busy.
Definition errno.h:382
static int process_running(struct process *process)
Check if process is running.
Definition process.h:176
struct xfer_buffer data_in
Data-in buffer.
Definition scsi.h:258
struct xfer_buffer data_out
Data-out buffer.
Definition scsi.h:256
size_t len
Size of data.
Definition xferbuf.h:25
static uint16_t usbblk_tag
Next command tag.
Definition usbblk.c:551
static int usbblk_out_command(struct usbblk_device *usbblk)
Issue bulk OUT command.
Definition usbblk.c:149
#define USBBLK_TAG_MAGIC
Command tag magic.
Definition usbblk.h:108

References assert, cmd, usbblk_device::cmd, scsi_cmd::data_in, scsi_cmd::data_out, DBGC, EBUSY, EOPNOTSUPP, usbblk_device::func, xfer_buffer::len, memcpy(), memset(), usb_function::name, usbblk_device::process, process_add(), process_running(), rc, usbblk_out_command(), usbblk_tag, and USBBLK_TAG_MAGIC.

Referenced by usbblk_scsi_command().

◆ usbblk_scsi_window()

size_t usbblk_scsi_window ( struct usbblk_device * usbblk)
static

Check SCSI command flow-control window.

Parameters
usbblkUSB block device
Return values
lenLength of window

Definition at line 652 of file usbblk.c.

652 {
653 struct usbblk_command *cmd = &usbblk->cmd;
654
655 /* Allow a single command if no command is currently in progress */
656 return ( cmd->tag ? 0 : 1 );
657}

References cmd, and usbblk_device::cmd.

◆ usbblk_scsi_command()

int usbblk_scsi_command ( struct usbblk_device * usbblk,
struct interface * data,
struct scsi_cmd * scsicmd )
static

Issue SCSI command.

Parameters
usbblkUSB block device
dataSCSI data interface
scsicmdSCSI command
Return values
tagCommand tag, or negative error

Definition at line 667 of file usbblk.c.

669 {
670 struct usbblk_command *cmd = &usbblk->cmd;
671 int rc;
672
673 /* (Re)open endpoints if needed */
674 if ( ( ! usbblk->in.open ) && ( ( rc = usbblk_open ( usbblk ) ) != 0 ) )
675 goto err_open;
676
677 /* Start new command */
678 if ( ( rc = usbblk_start ( usbblk, scsicmd ) ) != 0 )
679 goto err_start;
680
681 /* Attach to parent interface and return */
682 intf_plug_plug ( &usbblk->data, data );
683 return cmd->tag;
684
685 usbblk_stop ( usbblk, rc );
686 err_start:
687 usbblk_close ( usbblk );
688 err_open:
689 return rc;
690}
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static int usbblk_open(struct usbblk_device *usbblk)
Open endpoints.
Definition usbblk.c:63
static int usbblk_start(struct usbblk_device *usbblk, struct scsi_cmd *scsicmd)
Start new SCSI command.
Definition usbblk.c:585

References cmd, usbblk_device::cmd, data, usbblk_device::data, usbblk_device::in, intf_plug_plug(), usb_endpoint::open, rc, usbblk_close(), usbblk_open(), usbblk_start(), and usbblk_stop().

◆ usbblk_scsi_close()

void usbblk_scsi_close ( struct usbblk_device * usbblk,
int rc )
static

Close SCSI interface.

Parameters
usbblkUSB block device
rcReason for close

Definition at line 698 of file usbblk.c.

698 {
699
700 /* Restart interfaces */
701 intfs_restart ( rc, &usbblk->scsi, &usbblk->data, NULL );
702
703 /* Stop any in-progress command */
704 usbblk_stop ( usbblk, rc );
705
706 /* Close endpoints */
707 usbblk_close ( usbblk );
708
709 /* Flag as closed */
710 usbblk->opened = 0;
711}
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
Definition interface.c:387
int opened
Device opened flag.
Definition usbblk.h:98
struct interface scsi
SCSI command-issuing interface.
Definition usbblk.h:92

References usbblk_device::data, intfs_restart(), NULL, usbblk_device::opened, rc, usbblk_device::scsi, usbblk_close(), and usbblk_stop().

Referenced by usbblk_remove().

◆ usbblk_efi_describe()

EFI_DEVICE_PATH_PROTOCOL * usbblk_efi_describe ( struct usbblk_device * usbblk)
static

Describe as an EFI device path.

Parameters
usbblkUSB block device
Return values
pathEFI device path, or NULL on error

Definition at line 720 of file usbblk.c.

720 {
721
722 return efi_usb_path ( usbblk->func );
723}
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path(struct usb_function *func)
Construct EFI device path for USB function.
Definition efi_path.c:726

References efi_usb_path(), and usbblk_device::func.

◆ usbblk_find()

struct usbblk_device * usbblk_find ( const char * name)
static

Find USB block device.

Parameters
nameUSB block device name
Return values
usbblkUSB block device, or NULL

Definition at line 751 of file usbblk.c.

751 {
752 struct usbblk_device *usbblk;
753
754 /* Look for matching device */
755 list_for_each_entry ( usbblk, &usbblk_devices, list ) {
756 if ( strcmp ( usbblk->func->name, name ) == 0 )
757 return usbblk;
758 }
759
760 return NULL;
761}
const char * name
Definition ath9k_hw.c:1986
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
struct list_head list
List of devices.
Definition usbblk.h:82

References usbblk_device::func, usbblk_device::list, list_for_each_entry, name, usb_function::name, NULL, and strcmp().

Referenced by usbblk_open_uri().

◆ usbblk_open_uri()

int usbblk_open_uri ( struct interface * parent,
struct uri * uri )
static

Open USB block device URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 770 of file usbblk.c.

770 {
771 static struct scsi_lun lun;
772 struct usbblk_device *usbblk;
773 int rc;
774
775 /* Sanity check */
776 if ( ! uri->opaque )
777 return -EINVAL;
778
779 /* Find matching device */
780 usbblk = usbblk_find ( uri->opaque );
781 if ( ! usbblk )
782 return -ENOENT;
783
784 /* Fail if device is already open */
785 if ( usbblk->opened )
786 return -EBUSY;
787
788 /* Open SCSI device */
789 if ( ( rc = scsi_open ( parent, &usbblk->scsi, &lun ) ) != 0 ) {
790 DBGC ( usbblk, "USBBLK %s could not open SCSI device: %s\n",
791 usbblk->func->name, strerror ( rc ) );
792 return rc;
793 }
794
795 /* Mark as opened */
796 usbblk->opened = 1;
797
798 return 0;
799}
uint8_t lun
Logical Unit Number.
Definition edd.h:3
#define ENOENT
No such file or directory.
Definition errno.h:558
#define EINVAL
Invalid argument.
Definition errno.h:472
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition scsi.c:987
A SCSI LUN.
Definition scsi.h:237
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71
static struct usbblk_device * usbblk_find(const char *name)
Find USB block device.
Definition usbblk.c:751

References DBGC, EBUSY, EINVAL, ENOENT, usbblk_device::func, lun, usb_function::name, uri::opaque, usbblk_device::opened, rc, usbblk_device::scsi, scsi_open(), strerror(), and usbblk_find().

◆ usbblk_probe()

int usbblk_probe ( struct usb_function * func,
struct usb_configuration_descriptor * config )
static

Probe device.

Parameters
funcUSB function
configConfiguration descriptor
Return values
rcReturn status code

Definition at line 821 of file usbblk.c.

822 {
823 struct usb_device *usb = func->usb;
824 struct usbblk_device *usbblk;
826 int rc;
827
828 /* Allocate and initialise structure */
829 usbblk = zalloc ( sizeof ( *usbblk ) );
830 if ( ! usbblk ) {
831 rc = -ENOMEM;
832 goto err_alloc;
833 }
834 usbblk->func = func;
835 usb_endpoint_init ( &usbblk->out, usb, &usbblk_out_operations );
836 usb_endpoint_init ( &usbblk->in, usb, &usbblk_in_operations );
838 intf_init ( &usbblk->scsi, &usbblk_scsi_desc, &usbblk->refcnt );
839 intf_init ( &usbblk->data, &usbblk_data_desc, &usbblk->refcnt );
841 &usbblk->refcnt );
842
843 /* Locate interface descriptor */
844 desc = usb_interface_descriptor ( config, func->interface[0], 0 );
845 if ( ! desc ) {
846 DBGC ( usbblk, "USBBLK %s missing interface descriptor\n",
847 usbblk->func->name );
848 rc = -ENOENT;
849 goto err_desc;
850 }
851
852 /* Describe endpoints */
853 if ( ( rc = usb_endpoint_described ( &usbblk->out, config, desc,
854 USB_BULK_OUT, 0 ) ) != 0 ) {
855 DBGC ( usbblk, "USBBLK %s could not describe bulk OUT: %s\n",
856 usbblk->func->name, strerror ( rc ) );
857 goto err_out;
858 }
859 if ( ( rc = usb_endpoint_described ( &usbblk->in, config, desc,
860 USB_BULK_IN, 0 ) ) != 0 ) {
861 DBGC ( usbblk, "USBBLK %s could not describe bulk IN: %s\n",
862 usbblk->func->name, strerror ( rc ) );
863 goto err_in;
864 }
865
866 /* Add to list of devices */
867 list_add_tail ( &usbblk->list, &usbblk_devices );
868
869 usb_func_set_drvdata ( func, usbblk );
870 return 0;
871
872 err_in:
873 err_out:
874 err_desc:
875 ref_put ( &usbblk->refcnt );
876 err_alloc:
877 return rc;
878}
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define USB_BULK_OUT
Bulk OUT endpoint (internal) type.
Definition usb.h:296
static void usb_endpoint_init(struct usb_endpoint *ep, struct usb_device *usb, struct usb_endpoint_driver_operations *driver)
Initialise USB endpoint.
Definition usb.h:550
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition usb.h:627
#define USB_BULK_IN
Bulk IN endpoint (internal) type.
Definition usb.h:299
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:717
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition process.h:146
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
uint8_t interface[0]
List of interface numbers.
Definition usb.h:707
A USB interface descriptor.
Definition usb.h:245
struct refcnt refcnt
Reference count.
Definition usbblk.h:80
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.
Definition usb.c:241
struct usb_interface_descriptor * usb_interface_descriptor(struct usb_configuration_descriptor *config, unsigned int interface, unsigned int alternate)
Locate USB interface descriptor.
Definition usb.c:143
static struct interface_descriptor usbblk_scsi_desc
SCSI command interface descriptor.
Definition usbblk.c:735
static struct usb_endpoint_driver_operations usbblk_in_operations
Bulk IN endpoint operations.
Definition usbblk.c:514
static struct usb_endpoint_driver_operations usbblk_out_operations
Bulk OUT endpoint operations.
Definition usbblk.c:314
static struct process_descriptor usbblk_process_desc
Refill process descriptor.
Definition usbblk.c:540
static struct interface_descriptor usbblk_data_desc
SCSI data interface descriptor.
Definition usbblk.c:643

References usbblk_device::data, DBGC, desc, ENOENT, ENOMEM, usbblk_device::func, usbblk_device::in, usb_function::interface, intf_init(), usbblk_device::list, list_add_tail, usb_function::name, usbblk_device::out, usbblk_device::process, process_init_stopped(), rc, ref_put, usbblk_device::refcnt, usbblk_device::scsi, strerror(), usb_function::usb, USB_BULK_IN, USB_BULK_OUT, usb_endpoint_described(), usb_endpoint_init(), usb_func_set_drvdata(), usb_interface_descriptor(), usb_refill_init(), usbblk_data_desc, usbblk_in_operations, USBBLK_MAX_FILL, USBBLK_MAX_LEN, usbblk_out_operations, usbblk_process_desc, usbblk_scsi_desc, and zalloc().

◆ usbblk_remove()

void usbblk_remove ( struct usb_function * func)
static

Remove device.

Parameters
funcUSB function

Definition at line 885 of file usbblk.c.

885 {
886 struct usbblk_device *usbblk = usb_func_get_drvdata ( func );
887
888 /* Remove from list of devices */
889 list_del ( &usbblk->list );
890
891 /* Close all interfaces */
892 usbblk_scsi_close ( usbblk, -ENODEV );
893
894 /* Shut down interfaces */
895 intfs_shutdown ( -ENODEV, &usbblk->scsi, &usbblk->data, NULL );
896
897 /* Drop reference */
898 ref_put ( &usbblk->refcnt );
899}
#define ENODEV
No such device.
Definition errno.h:553
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:728
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition interface.c:327
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void usbblk_scsi_close(struct usbblk_device *usbblk, int rc)
Close SCSI interface.
Definition usbblk.c:698

References usbblk_device::data, ENODEV, usbblk_device::func, intfs_shutdown(), usbblk_device::list, list_del, NULL, ref_put, usbblk_device::refcnt, usbblk_device::scsi, usb_func_get_drvdata(), and usbblk_scsi_close().

Variable Documentation

◆ usbblk_out_operations

struct usb_endpoint_driver_operations usbblk_out_operations
static
Initial value:
= {
.complete = usbblk_out_complete,
}
static void usbblk_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition usbblk.c:278

Bulk OUT endpoint operations.

Definition at line 314 of file usbblk.c.

314 {
315 .complete = usbblk_out_complete,
316};

Referenced by usbblk_probe().

◆ usbblk_in_operations

struct usb_endpoint_driver_operations usbblk_in_operations
static
Initial value:
= {
.complete = usbblk_in_complete,
}
static void usbblk_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition usbblk.c:454

Bulk IN endpoint operations.

Definition at line 514 of file usbblk.c.

514 {
515 .complete = usbblk_in_complete,
516};

Referenced by usbblk_probe().

◆ usbblk_process_desc

struct process_descriptor usbblk_process_desc
static
Initial value:
=
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
A process.
Definition process.h:18
static void usbblk_step(struct usbblk_device *usbblk)
Refill endpoints.
Definition usbblk.c:530

Refill process descriptor.

Definition at line 540 of file usbblk.c.

Referenced by usbblk_probe().

◆ usbblk_tag

uint16_t usbblk_tag
static

Next command tag.

Definition at line 551 of file usbblk.c.

Referenced by usbblk_start().

◆ usbblk_data_operations

struct interface_operation usbblk_data_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

SCSI data interface operations.

Definition at line 638 of file usbblk.c.

638 {
640};

◆ usbblk_data_desc

struct interface_descriptor usbblk_data_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation usbblk_data_operations[]
SCSI data interface operations.
Definition usbblk.c:638

SCSI data interface descriptor.

Definition at line 643 of file usbblk.c.

Referenced by usbblk_probe().

◆ usbblk_scsi_operations

struct interface_operation usbblk_scsi_operations[]
static
Initial value:
= {
}
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:949
#define EFI_INTF_OP
Definition efi.h:381
A SCSI command.
Definition scsi.c:263
static int usbblk_scsi_command(struct usbblk_device *usbblk, struct interface *data, struct scsi_cmd *scsicmd)
Issue SCSI command.
Definition usbblk.c:667
static size_t usbblk_scsi_window(struct usbblk_device *usbblk)
Check SCSI command flow-control window.
Definition usbblk.c:652
static EFI_DEVICE_PATH_PROTOCOL * usbblk_efi_describe(struct usbblk_device *usbblk)
Describe as an EFI device path.
Definition usbblk.c:720
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

SCSI command interface operations.

Definition at line 726 of file usbblk.c.

◆ usbblk_scsi_desc

struct interface_descriptor usbblk_scsi_desc
static
Initial value:
=
static struct interface_operation usbblk_scsi_operations[]
SCSI command interface operations.
Definition usbblk.c:726

SCSI command interface descriptor.

Definition at line 735 of file usbblk.c.

Referenced by usbblk_probe().

◆ __uri_opener

struct uri_opener usbblk_uri_opener __uri_opener
Initial value:
= {
.scheme = "usb",
.open = usbblk_open_uri,
}
static int usbblk_open_uri(struct interface *parent, struct uri *uri)
Open USB block device URI.
Definition usbblk.c:770

USB block device URI opener.

Definition at line 802 of file usbblk.c.

802 {
803 .scheme = "usb",
804 .open = usbblk_open_uri,
805};

◆ usbblk_ids

struct usb_device_id usbblk_ids[]
static
Initial value:
= {
USB_ID ( 0xffff, 0xffff, "usbblk", "USB block device", 0 ),
}
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1383

Mass storage class device IDs.

Definition at line 902 of file usbblk.c.

902 {
903 USB_ID ( 0xffff, 0xffff, "usbblk", "USB block device", 0 ),
904};

◆ __usb_driver

struct usb_driver usbblk_driver __usb_driver
Initial value:
= {
.ids = usbblk_ids,
.id_count = ( sizeof ( usbblk_ids ) / sizeof ( usbblk_ids[0] ) ),
.score = USB_SCORE_NORMAL,
.probe = usbblk_probe,
.remove = usbblk_remove,
}
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1411
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1475
static int usbblk_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition usbblk.c:821
static struct usb_device_id usbblk_ids[]
Mass storage class device IDs.
Definition usbblk.c:902
static void usbblk_remove(struct usb_function *func)
Remove device.
Definition usbblk.c:885
#define USB_PROTOCOL_MSC_BULK
Bulk-only transport protocol.
Definition usbblk.h:25
#define USB_CLASS_MSC
Mass storage class code.
Definition usbblk.h:19
#define USB_SUBCLASS_MSC_SCSI
SCSI command set subclass code.
Definition usbblk.h:22

Mass storage driver.

Definition at line 907 of file usbblk.c.

907 {
908 .ids = usbblk_ids,
909 .id_count = ( sizeof ( usbblk_ids ) / sizeof ( usbblk_ids[0] ) ),
912 .score = USB_SCORE_NORMAL,
913 .probe = usbblk_probe,
914 .remove = usbblk_remove,
915};