1 /* 2 * Copyright 2004-2008, 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_BUSMANAGER_H 8 #define _SCSI_BUSMANAGER_H 9 10 /* 11 SCSI bus manager interface 12 13 The bus manager interface is _based_ on CAM, but I've modified it because :- 14 - HBA engine, target mode and queue freezing (and probably other features) 15 aren't supported (at least the first two aren't supported by linux too ;) 16 - Asynchronous events aren't supported (no OS/driver I know uses them) 17 - P/T/L was defined by number not by handle, requiring many redundant tests 18 and thus making adding/removing of devices/busses very hard, especially if 19 PnP is to be supported 20 - single entry system as proposed by CAM involves extra tests and overhead 21 because of generalized data structure 22 23 24 For peripheral driver writers: 25 26 Something about requests involving data transfer: you can either specify 27 the virtual address in <data> of CCB (in which case it must be continuous), 28 or store a pointer to a S/G list that contains physical addresses in 29 <sg_list>/<sg_count>. If <sg_list> is non-Null, <data> is ignored. 30 The S/G list must be in kernel space because the request can be executed 31 in a different thread context. This is also the reason why the S/G list has 32 to contain physical addresses. For obvious reason, the data buffer specified 33 by <sg_list> must be locked, but <data> doesn't need to be. 34 35 You can either execute the request synchronously ("sync_io") or 36 asynchronously ("async_io"; you have to acquire <completion_sem> to find 37 out when the request is finished). In the first case you can use either 38 <data> or <sg_list>, in the latter <sg_list> only. 39 40 The SCSI bus manager takes care that the controller can access the data 41 via DMA by copying it into a buffer if necessary. For the paging path, 42 this can lead to problems (if the system writes a page to disk and the SCSI 43 bus manager has to allocate a buffer during execution you are in trouble), 44 therefore the blk_man takes care that is not necessary for reads/writes. 45 To safe some microseconds, you should set the SCSI_DMA_SAFE flag for these 46 requests, so the SCSI bus manager ommittes the test. 47 48 Effectively, using synchronous execution and specifying the address via 49 <data> is a safe bet. 50 51 52 For SIM writers: 53 54 Requests sent by peripheral drivers are forwarded to the <scsi_io> entry 55 of the SIM. You should return as soon as some waiting is required. 56 Usually, the controller raises an IRQ when a request can be continued 57 or is finished. As interrupt handlers must be as fast as possible, you 58 can schedule a DPC in the handler (<schedule_dpc>) which executed by a 59 high priority service thread that is spawned by the SCSI bus manager 60 for each bus. This service thread also takes care to submit waiting 61 requests. 62 63 You can specify a maximum number of concurrent requests per bus via 64 path_inquiry (<hba_queue_size>) for the bus. The device limit is 65 determined via INQUIRY. If you need a lower/dynamic limit, you can refuse 66 a request by <requeue>. If <bus_overflow> is true, no further requests 67 to the bus will be sent, if <bus_overflow> is false, no further requests 68 to the device will be sent. To terminate the overflow condition, call 69 <cont_send_device>/<cont_send_bus>. It also terminated when a request 70 for the bus/device is finished via <finished> or <resubmit>. 71 Because of the asynchronous nature, requests may still arrive after the 72 overflow condition being signalled, so you should add a safety test to 73 <scsi_io>. 74 75 If a problem occurs during execution, you can ask for a restart via 76 <resubmit>. The request in question will be submitted as soon as possible. 77 78 If you want to be not disturbed, you can block further requests via 79 <block_bus>/<block_device>. As said above, you must have a safety test 80 at <scsi_io> though. 81 82 If the SIM uses a non-SCSI protocol, it can ask the SCSI bus manager 83 to emulate unsupported SCSI commands by translating them other (supported) 84 commands. The bus manager calls <get_restriction> during detection for 85 each device, setting <is_atapi> on return makes the bus manager translate 86 READ6/WRITE6 commands to READ10/WRITE10 commands, MODE REQUEST6/SENSE6 87 to MODE REQUEST10/SENSE10 and fix the version fields of INQUIRY results, 88 so ATAPI devices can be used like standard SCSI devices. Further, the 89 SCSI bus manager can emulate auto-sense by executing a REQUEST SENSE 90 if <subsys_status> is SCSI_REQ_CMP_ERR and <device_status> is 91 SCSI_STATUS_CHECK_CONDITION when a request is finished. This emulation 92 may be enhanced/generalized in the future. 93 */ 94 95 96 #include <KernelExport.h> 97 98 #ifdef _KERNEL_MODE 99 #include <condition_variable.h> 100 #include <device_manager.h> 101 #endif 102 103 104 typedef struct scsi_bus_info *scsi_bus; 105 typedef struct scsi_device_info *scsi_device; 106 107 108 #if defined(__cplusplus) && defined(_KERNEL_MODE) 109 // structure of one scsi i/o CCB (command control block) 110 typedef struct scsi_ccb { 111 struct scsi_ccb *next, *prev; // internal 112 113 uchar subsys_status; // Returned subsystem status 114 uchar device_status; // Returned scsi device status 115 116 uchar path_id; // Path ID for the request 117 uchar target_id; // Target device ID 118 uchar target_lun; // Target LUN number 119 uint32 flags; // Flags for operation of the subsystem 120 121 // notified after asynchronous execution of request 122 ConditionVariable completion_cond; 123 124 #define SCSI_MAX_CDB_SIZE 16 125 uint8 cdb[SCSI_MAX_CDB_SIZE]; // command data block 126 uchar cdb_length; // length of command in bytes 127 int64 sort; // value of command to sort on (<0 means n/a) 128 bigtime_t timeout; // timeout - 0 = use default 129 130 uchar *data; // pointer to data 131 const physical_entry *sg_list; // scatter/gather list 132 uint16 sg_count; // number of S/G entries 133 uint32 data_length; // length of data 134 int32 data_resid; // data transfer residual length: 2's comp 135 void *io_operation; 136 137 #define SCSI_MAX_SENSE_SIZE 64 138 uchar sense[SCSI_MAX_SENSE_SIZE]; // autosense data 139 uchar sense_resid; // autosense resid length: 2's comp 140 141 // private 142 bool ordered : 1; // request cannot overtake/be overtaken by others 143 bool buffered : 1; // data is buffered to make it DMA safe 144 bool emulated : 1; // command is executed as part of emulation 145 146 scsi_bus bus; // associated bus 147 scsi_device device; // associated device 148 struct dma_buffer *dma_buffer; // used dma buffer, or NULL 149 uchar state; // bus manager state 150 151 // original data before command emulation was applied 152 uint8 orig_cdb[SCSI_MAX_CDB_SIZE]; 153 uchar orig_cdb_length; 154 const physical_entry *orig_sg_list; 155 uint16 orig_sg_count; 156 uint32 orig_data_length; 157 } scsi_ccb; 158 #else 159 typedef struct scsi_ccb scsi_ccb; 160 #endif 161 162 163 // Defines for the subsystem status field 164 165 #define SCSI_REQ_INPROG 0x00 /* request is in progress */ 166 #define SCSI_REQ_CMP 0x01 /* request completed w/out error */ 167 #define SCSI_REQ_ABORTED 0x02 /* request aborted by the host */ 168 #define SCSI_UA_ABORT 0x03 /* Unable to Abort request */ 169 #define SCSI_REQ_CMP_ERR 0x04 /* request completed with an err */ 170 #define SCSI_BUSY 0x05 /* subsystem is busy */ 171 #define SCSI_REQ_INVALID 0x06 /* request is invalid */ 172 #define SCSI_PATH_INVALID 0x07 /* Path ID supplied is invalid */ 173 #define SCSI_DEV_NOT_THERE 0x08 /* SCSI device not installed/there */ 174 #define SCSI_UA_TERMIO 0x09 /* Unable to Terminate I/O req */ 175 #define SCSI_SEL_TIMEOUT 0x0A /* Target selection timeout */ 176 #define SCSI_CMD_TIMEOUT 0x0B /* Command timeout */ 177 #define SCSI_MSG_REJECT_REC 0x0D /* Message reject received */ 178 #define SCSI_SCSI_BUS_RESET 0x0E /* SCSI bus reset sent/received */ 179 #define SCSI_UNCOR_PARITY 0x0F /* Uncorrectable parity err occurred */ 180 #define SCSI_AUTOSENSE_FAIL 0x10 /* Autosense: Request sense cmd fail */ 181 #define SCSI_NO_HBA 0x11 /* No HBA detected Error */ 182 #define SCSI_DATA_RUN_ERR 0x12 /* Data overrun/underrun error */ 183 #define SCSI_UNEXP_BUSFREE 0x13 /* Unexpected BUS free */ 184 #define SCSI_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ 185 #define SCSI_PROVIDE_FAIL 0x16 /* Unable to provide requ. capability */ 186 #define SCSI_BDR_SENT 0x17 /* A SCSI BDR msg was sent to target */ 187 #define SCSI_REQ_TERMIO 0x18 /* request terminated by the host */ 188 #define SCSI_HBA_ERR 0x19 /* Unrecoverable host bus adaptor err*/ 189 #define SCSI_BUS_RESET_DENIED 0x1A /* SCSI bus reset denied */ 190 191 #define SCSI_IDE 0x33 /* Initiator Detected Error Received */ 192 #define SCSI_RESRC_UNAVAIL 0x34 /* Resource unavailable */ 193 #define SCSI_UNACKED_EVENT 0x35 /* Unacknowledged event by host */ 194 #define SCSI_LUN_INVALID 0x38 /* LUN supplied is invalid */ 195 #define SCSI_TID_INVALID 0x39 /* Target ID supplied is invalid */ 196 #define SCSI_FUNC_NOTAVAIL 0x3A /* The requ. func is not available */ 197 #define SCSI_NO_NEXUS 0x3B /* Nexus is not established */ 198 #define SCSI_IID_INVALID 0x3C /* The initiator ID is invalid */ 199 #define SCSI_CDB_RECVD 0x3D /* The SCSI CDB has been received */ 200 #define SCSI_LUN_ALLREADY_ENAB 0x3E /* LUN already enabled */ 201 #define SCSI_SCSI_BUSY 0x3F /* SCSI bus busy */ 202 203 #define SCSI_AUTOSNS_VALID 0x80 /* Autosense data valid for target */ 204 205 #define SCSI_SUBSYS_STATUS_MASK 0x3F /* Mask bits for just the status # */ 206 207 208 // Defines for the flags field 209 210 #define SCSI_DIR_RESV 0x00000000 /* Data direction (00: reserved) */ 211 #define SCSI_DIR_IN 0x00000040 /* Data direction (01: DATA IN) */ 212 #define SCSI_DIR_OUT 0x00000080 /* Data direction (10: DATA OUT) */ 213 #define SCSI_DIR_NONE 0x000000C0 /* Data direction (11: no data) */ 214 #define SCSI_DIR_MASK 0x000000C0 215 216 #define SCSI_DIS_AUTOSENSE 0x00000020 /* Disable autosense feature */ 217 #define SCSI_ORDERED_QTAG 0x00000010 // ordered queue (cannot overtake/be overtaken) 218 #define SCSI_DMA_SAFE 0x00000008 // set if data buffer is DMA approved 219 220 #define SCSI_DIS_DISCONNECT 0x00008000 /* Disable disconnect */ 221 #define SCSI_INITIATE_SYNC 0x00004000 /* Attempt Sync data xfer, and SDTR */ 222 #define SCSI_DIS_SYNC 0x00002000 /* Disable sync, go to async */ 223 #define SCSI_ENG_SYNC 0x00000200 /* Flush resid bytes before cmplt */ 224 225 226 // Defines for the Path Inquiry CCB fields 227 228 // flags in hba_inquiry 229 #define SCSI_PI_MDP_ABLE 0x80 /* Supports MDP message */ 230 #define SCSI_PI_WIDE_32 0x40 /* Supports 32 bit wide SCSI */ 231 #define SCSI_PI_WIDE_16 0x20 /* Supports 16 bit wide SCSI */ 232 #define SCSI_PI_SDTR_ABLE 0x10 /* Supports SDTR message */ 233 #define SCSI_PI_TAG_ABLE 0x02 /* Supports tag queue message */ 234 #define SCSI_PI_SOFT_RST 0x01 /* Supports soft reset */ 235 236 // flags in hba_misc 237 #define SCSI_PIM_SCANHILO 0x80 /* Bus scans from ID 7 to ID 0 */ 238 #define SCSI_PIM_NOREMOVE 0x40 /* Removable dev not included in scan */ 239 240 // sizes of inquiry fields 241 #define SCSI_VUHBA 14 /* Vendor Unique HBA length */ 242 #define SCSI_SIM_ID 16 /* ASCII string len for SIM ID */ 243 #define SCSI_HBA_ID 16 /* ASCII string len for HBA ID */ 244 #define SCSI_FAM_ID 16 /* ASCII string len for FAMILY ID */ 245 #define SCSI_TYPE_ID 16 /* ASCII string len for TYPE ID */ 246 #define SCSI_VERS 8 /* ASCII string len for SIM & HBA vers */ 247 248 249 // Path inquiry, extended by BeOS XPT_EXTENDED_PATH_INQ parameters 250 typedef struct { 251 uchar version_num; /* Version number for the SIM/HBA */ 252 uchar hba_inquiry; /* Mimic of INQ byte 7 for the HBA */ 253 uchar hba_misc; /* Misc HBA feature flags */ 254 uchar vuhba_flags[SCSI_VUHBA];/* Vendor unique capabilities */ 255 uchar initiator_id; /* ID of the HBA on the SCSI bus */ 256 uint32 hba_queue_size; // size of adapters command queue 257 char sim_vid[SCSI_SIM_ID]; /* Vendor ID of the SIM */ 258 char hba_vid[SCSI_HBA_ID]; /* Vendor ID of the HBA */ 259 260 char sim_version[SCSI_VERS]; /* SIM version number */ 261 char hba_version[SCSI_VERS]; /* HBA version number */ 262 char controller_family[SCSI_FAM_ID]; /* Controller family */ 263 char controller_type[SCSI_TYPE_ID]; /* Controller type */ 264 } scsi_path_inquiry; 265 266 267 // Device node 268 269 // target (uint8) 270 #define SCSI_DEVICE_TARGET_ID_ITEM "scsi/target_id" 271 // lun (uint8) 272 #define SCSI_DEVICE_TARGET_LUN_ITEM "scsi/target_lun" 273 // node type 274 #define SCSI_DEVICE_TYPE_NAME "scsi/device/v1" 275 // device inquiry data (raw scsi_res_inquiry) 276 #define SCSI_DEVICE_INQUIRY_ITEM "scsi/device_inquiry" 277 // device type (uint8) 278 #define SCSI_DEVICE_TYPE_ITEM "scsi/type" 279 // vendor name (string) 280 #define SCSI_DEVICE_VENDOR_ITEM "scsi/vendor" 281 // product name (string) 282 #define SCSI_DEVICE_PRODUCT_ITEM "scsi/product" 283 // revision (string) 284 #define SCSI_DEVICE_REVISION_ITEM "scsi/revision" 285 286 // maximum targets on scsi bus 287 #define SCSI_DEVICE_MAX_TARGET_COUNT "scsi/max_target_count" 288 // maximum luns on scsi bus 289 #define SCSI_DEVICE_MAX_LUN_COUNT "scsi/max_lun_count" 290 291 // directory containing links to peripheral drivers 292 #define SCSI_PERIPHERAL_DRIVERS_DIR "scsi" 293 294 // bus manager device interface for peripheral driver 295 typedef struct scsi_device_interface { 296 driver_module_info info; 297 298 scsi_ccb *(*alloc_ccb)(scsi_device device); 299 void (*free_ccb)(scsi_ccb *ccb); 300 301 // execute command asynchronously 302 // when it's finished, the condvar of the ccb is released 303 // you must provide a S/G list if data_len != 0 304 void (*async_io)(scsi_ccb *ccb); 305 // execute command synchronously 306 // you don't need to provide a S/G list nor have to lock data 307 void (*sync_io)(scsi_ccb *ccb); 308 309 // abort request 310 uchar (*abort)(scsi_ccb *ccb_to_abort); 311 // reset device 312 uchar (*reset_device)(scsi_device device); 313 // terminate request 314 uchar (*term_io)(scsi_ccb *ccb_to_terminate); 315 316 status_t (*ioctl)(scsi_device device, uint32 op, void *buffer, size_t length); 317 } scsi_device_interface; 318 319 #define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/device/driver_v1" 320 321 322 // Bus node 323 324 // attributes: 325 326 // path (uint8) 327 #define SCSI_BUS_PATH_ID_ITEM "scsi/path_id" 328 // node type 329 #define SCSI_BUS_TYPE_NAME "scsi/bus" 330 331 // SCSI bus node driver. 332 // This interface can be used by peripheral drivers to access the 333 // bus directly. 334 typedef struct scsi_bus_interface { 335 driver_module_info info; 336 337 // get information about host controller 338 uchar (*path_inquiry)(scsi_bus bus, scsi_path_inquiry *inquiry_data); 339 // reset SCSI bus 340 uchar (*reset_bus)(scsi_bus bus); 341 } scsi_bus_interface; 342 343 // name of SCSI bus node driver 344 #define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/driver_v1" 345 346 347 // Interface for SIM 348 349 // cookie for dpc 350 typedef struct scsi_dpc_info *scsi_dpc_cookie; 351 352 // Bus manager interface used by SCSI controller drivers. 353 // SCSI controller drivers get this interface passed via their init_device 354 // method. Further, they must specify this driver as their fixed consumer. 355 typedef struct scsi_for_sim_interface { 356 driver_module_info info; 357 358 // put request into wait queue because of overflow 359 // bus_overflow: true - too many bus requests 360 // false - too many device requests 361 // bus/device won't receive requests until cont_sent_bus/cont_send_device 362 // is called or a request is finished via finished(); 363 // to avoid race conditions (reporting a full and a available bus at once) 364 // the SIM should synchronize calls to requeue, resubmit and finished 365 void (*requeue)(scsi_ccb *ccb, bool bus_overflow); 366 // resubmit request ASAP 367 // to be used if execution of request went wrong and must be retried 368 void (*resubmit)(scsi_ccb *ccb); 369 // mark request as being finished 370 // num_requests: number of requests that were handled by device 371 // when the request was sent (read: how full was the device 372 // queue); needed to find out how large the device queue is; 373 // e.g. if three were already running plus this request makes 374 // num_requests=4 375 void (*finished)(scsi_ccb *ccb, uint num_requests); 376 377 // following functions return error on invalid arguments only 378 status_t (*alloc_dpc)(scsi_dpc_cookie *dpc); 379 status_t (*free_dpc)(scsi_dpc_cookie dpc); 380 status_t (*schedule_dpc)(scsi_bus cookie, scsi_dpc_cookie dpc, /*int flags,*/ 381 void (*func)( void * ), void *arg); 382 383 // block entire bus (can be nested) 384 // no more request will be submitted to this bus 385 void (*block_bus)(scsi_bus bus); 386 // unblock entire bus 387 // requests will be submitted to bus ASAP 388 void (*unblock_bus)(scsi_bus bus); 389 // block one device 390 // no more requests will be submitted to this device 391 void (*block_device)(scsi_device device); 392 // unblock device 393 // requests for this device will be submitted ASAP 394 void (*unblock_device)(scsi_device device); 395 396 // terminate bus overflow condition (see "requeue") 397 void (*cont_send_bus)(scsi_bus bus); 398 // terminate device overflow condition (see "requeue") 399 void (*cont_send_device)(scsi_device device); 400 } scsi_for_sim_interface; 401 402 403 #define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/driver_v1" 404 405 406 // SIM Node 407 408 // attributes: 409 410 // node type 411 #define SCSI_SIM_TYPE_NAME "bus/scsi/v1" 412 // controller name (required, string) 413 #define SCSI_DESCRIPTION_CONTROLLER_NAME "controller_name" 414 415 typedef void *scsi_sim_cookie; 416 417 // SIM interface 418 // SCSI controller drivers must provide this interface 419 typedef struct scsi_sim_interface { 420 driver_module_info info; 421 422 void (*set_scsi_bus)(scsi_sim_cookie cookie, scsi_bus bus); 423 424 // execute request 425 void (*scsi_io)(scsi_sim_cookie cookie, scsi_ccb *ccb); 426 // abort request 427 uchar (*abort)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort); 428 // reset device 429 uchar (*reset_device)(scsi_sim_cookie cookie, uchar target_id, uchar target_lun); 430 // terminate request 431 uchar (*term_io)(scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate); 432 433 // get information about bus 434 uchar (*path_inquiry)(scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data); 435 // scan bus 436 // this is called immediately before the SCSI bus manager scans the bus 437 uchar (*scan_bus)(scsi_sim_cookie cookie); 438 // reset bus 439 uchar (*reset_bus)(scsi_sim_cookie cookie); 440 441 // get restrictions of one device 442 // (used for non-SCSI transport protocols and bug fixes) 443 void (*get_restrictions)(scsi_sim_cookie cookie, 444 uchar target_id, // target id 445 bool *is_atapi, // set to true if this is an ATAPI device that 446 // needs some commands emulated 447 bool *no_autosense, // set to true if there is no autosense; 448 // the SCSI bus manager will request sense on 449 // SCSI_REQ_CMP_ERR/SCSI_STATUS_CHECK_CONDITION 450 uint32 *max_blocks ); // maximum number of blocks per transfer if > 0; 451 // used for buggy devices that cannot handle 452 // large transfers (read: ATAPI ZIP drives) 453 454 status_t (*ioctl)(scsi_sim_cookie, uint8 targetID, uint32 op, void *buffer, size_t length); 455 } scsi_sim_interface; 456 457 458 #endif /* _SCSI_BUSMANAGER_H */ 459