1 /* 2 * Copyright 2004-2007, Haiku, Inc. All RightsReserved. 3 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 #ifndef _SCSI_PERIPH_H 8 #define _SCSI_PERIPH_H 9 10 /* 11 Use this module to minimize work required to write a SCSI 12 peripheral driver. 13 14 It takes care of: 15 - error handling 16 - medium changes (including restarting the medium) 17 - detection of medium capacity 18 */ 19 20 21 #include <bus/SCSI.h> 22 #include <block_io.h> 23 #include <scsi_cmds.h> 24 #include <Drivers.h> 25 26 // cookie issued by module per device 27 typedef struct scsi_periph_device_info *scsi_periph_device; 28 // cookie issued by module per file handle 29 typedef struct scsi_periph_handle_info *scsi_periph_handle; 30 31 // "standardized" error code to simplify handling of scsi errors 32 typedef enum { 33 err_act_ok, // executed successfully 34 err_act_retry, // failed, retry 3 times 35 err_act_fail, // failed, don't retry 36 err_act_many_retries, // failed, retry multiple times (currently 10 times) 37 err_act_start, // devices requires a "start" command 38 err_act_invalid_req // request is invalid 39 } err_act; 40 41 // packed scsi command result 42 typedef struct err_res { 43 status_t error_code : 32; // Be error code 44 uint32 action : 8; // err_act code 45 } err_res; 46 47 #define MK_ERROR( aaction, code ) ({ \ 48 err_res res = {error_code: (code), action: (aaction) }; \ 49 res; \ 50 }) 51 52 // device icon type 53 typedef enum { 54 icon_type_disk, 55 icon_type_removal, 56 icon_type_floppy, 57 icon_type_cd 58 } icon_type; 59 60 // cookie issued by driver to identify itself 61 //typedef struct periph_info *periph_cookie; 62 // cookie issued by driver per device 63 typedef struct periph_device_info *periph_device_cookie; 64 // cookie issued by driver per file handle 65 typedef struct periph_handle_info *periph_handle_cookie; 66 67 68 // callbacks to be provided by peripheral driver 69 typedef struct scsi_periph_callbacks { 70 // *** block devices *** 71 // informs of new size of medium 72 // (set to NULL if not a block device) 73 void (*set_capacity)( periph_device_cookie periph_device, uint64 capacity, 74 uint32 block_size ); 75 76 // *** removable devices 77 // called when media got changed (can be NULL if medium is not changable) 78 // (you don't need to call periph->media_changed, but it's doesn't if you do) 79 // ccb - request at your disposal 80 void (*media_changed)( periph_device_cookie periph_device, 81 scsi_ccb *request ); 82 } scsi_periph_callbacks; 83 84 85 // functions provided by this module 86 typedef struct scsi_periph_interface { 87 module_info info; 88 89 // *** init/cleanup *** 90 status_t (*register_device)( 91 periph_device_cookie periph_device, 92 scsi_periph_callbacks *callbacks, 93 scsi_device scsi_device, 94 scsi_device_interface *scsi, 95 device_node_handle node, 96 bool removable, 97 scsi_periph_device *driver ); 98 status_t (*unregister_device)( scsi_periph_device driver ); 99 100 // *** basic command execution *** 101 // exec command, retrying on problems 102 status_t (*safe_exec)( 103 scsi_periph_device periph_device, 104 scsi_ccb *request ); 105 // exec simple command 106 status_t (*simple_exec)( scsi_periph_device device, 107 void *cdb, uchar cdb_len, void *data, size_t data_len, 108 int ccb_flags ); 109 110 // *** file handling *** 111 // to be called when a new file is opened 112 status_t (*handle_open)( scsi_periph_device device, 113 periph_handle_cookie periph_handle, scsi_periph_handle *res_handle ); 114 // to be called when a file is closed 115 status_t (*handle_close)( scsi_periph_handle handle ); 116 // to be called when a file is freed 117 status_t (*handle_free)( scsi_periph_handle handle ); 118 119 // *** default implementation for block devices *** 120 // block read 121 // preferred_ccb_size - preferred command size; if zero, the shortest is used 122 status_t (*read)( scsi_periph_handle handle, const phys_vecs *vecs, 123 off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred, 124 int preferred_ccb_size ); 125 // block write 126 // (see block_read) 127 status_t (*write)( scsi_periph_handle handle, const phys_vecs *vecs, 128 off_t pos, size_t num_blocks, uint32 block_size, size_t *bytes_transferred, 129 int preferred_ccb_size ); 130 // block ioctls 131 status_t (*ioctl)( scsi_periph_handle handle, int op, void *buf, size_t len ); 132 // check medium capacity (calls set_capacity callback on success) 133 // request - ccb for this device; is used to talk to device 134 status_t (*check_capacity)( scsi_periph_device device, scsi_ccb *request ); 135 136 // *** removable media *** 137 // to be called when a medium change is detected to block subsequent commands 138 void (*media_changed)( scsi_periph_device device ); 139 // convert result of *request to err_res 140 err_res (*check_error)( scsi_periph_device device, scsi_ccb *request ); 141 // send start or stop command to device 142 // with_LoEj = true - include loading/ejecting, 143 // false - only do allow/deny 144 err_res (*send_start_stop)( scsi_periph_device device, scsi_ccb *request, 145 bool start, bool with_LoEj ); 146 // checks media status and waits for device to become ready 147 // returns: B_OK, B_DEV_MEDIA_CHANGE_REQUESTED, B_NO_MEMORY or 148 // pending error reported by handle_get_error 149 status_t (*get_media_status)( scsi_periph_handle handle ); 150 151 // compose device name consisting of prefix and path/target/LUN 152 // (result must be freed by caller) 153 char *(*compose_device_name)(device_node_handle device_node, const char *prefix); 154 155 // fill data with icon (for B_GET_ICON ioctl) 156 status_t (*get_icon)( icon_type type, device_icon *data ); 157 158 // synchronizes (flush) the device cache 159 err_res(*synchronize_cache)(scsi_periph_device device, scsi_ccb *request); 160 } scsi_periph_interface; 161 162 #define SCSI_PERIPH_MODULE_NAME "generic/scsi_periph/v1" 163 164 #endif /* _SCSI_PERIPH_H */ 165