* Copyright 2004-2013, Haiku, Inc. All RightsReserved.
* Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _SCSI_PERIPH_H
#define _SCSI_PERIPH_H
peripheral driver.
It takes care of:
- error handling
- medium changes (including restarting the medium)
- detection of medium capacity
*/
#include <bus/SCSI.h>
#include <scsi_cmds.h>
#include <Drivers.h>
typedef struct scsi_periph_device_info *scsi_periph_device;
typedef struct scsi_periph_handle_info *scsi_periph_handle;
typedef enum {
err_act_ok,
err_act_retry,
err_act_fail,
err_act_many_retries,
err_act_start,
err_act_invalid_req
} err_act;
typedef struct err_res {
status_t error_code : 32;
uint32 action : 8;
} err_res;
#define MK_ERROR( aaction, code ) ({ \
err_res _res = {.error_code = (code), .action = (aaction) }; \
_res; \
})
typedef struct periph_device_info *periph_device_cookie;
typedef struct periph_handle_info *periph_handle_cookie;
typedef struct IOOperation io_operation;
typedef struct scsi_periph_callbacks {
void (*set_capacity)(periph_device_cookie cookie, uint64 capacity,
uint32 blockSize, uint32 physicalBlockSize);
void (*media_changed)(periph_device_cookie cookie, scsi_ccb *request);
} scsi_periph_callbacks;
typedef struct scsi_block_range {
uint64 lba;
uint64 size;
} scsi_block_range;
typedef struct scsi_periph_interface {
module_info info;
status_t (*register_device)(periph_device_cookie cookie,
scsi_periph_callbacks *callbacks, scsi_device scsiDevice,
scsi_device_interface *scsi, device_node *node, bool removable,
int preferredCcbSize, scsi_periph_device *driver);
status_t (*unregister_device)(scsi_periph_device driver);
status_t (*safe_exec)(scsi_periph_device periphCookie, scsi_ccb *request);
status_t (*simple_exec)(scsi_periph_device device, void *cdb,
uint8 cdbLength, void *data, size_t dataLength, int ccbFlags);
status_t (*handle_open)(scsi_periph_device device,
periph_handle_cookie periph_handle, scsi_periph_handle *_handle);
status_t (*handle_close)(scsi_periph_handle handle);
status_t (*handle_free)(scsi_periph_handle handle);
status_t (*read_write)(scsi_periph_device_info *device, scsi_ccb *request,
uint64 offset, size_t numBlocks, physical_entry* vecs, size_t vecCount,
bool isWrite, size_t* _bytesTransferred);
status_t (*io)(scsi_periph_device device, io_operation *operation,
size_t *_bytesTransferred);
status_t (*ioctl)(scsi_periph_handle handle, int op, void *buffer,
size_t length);
status_t (*check_capacity)(scsi_periph_device device, scsi_ccb *request);
err_res (*synchronize_cache)(scsi_periph_device device, scsi_ccb *request);
status_t (*trim_device)(scsi_periph_device_info *device, scsi_ccb *request,
scsi_block_range* ranges, uint32 rangeCount, uint64* trimmedBlocks);
void (*media_changed)(scsi_periph_device device);
err_res (*check_error)(scsi_periph_device device, scsi_ccb *request);
err_res (*send_start_stop)(scsi_periph_device device, scsi_ccb *request,
bool start, bool withLoadEject);
status_t (*get_media_status)(scsi_periph_handle handle);
char *(*compose_device_name)(device_node *device_node, const char *prefix);
} scsi_periph_interface;
#define SCSI_PERIPH_MODULE_NAME "generic/scsi_periph/v1"
#endif