1 /* 2 * Copyright 2004-2006, 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_cnt>. 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_DEVICE_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 #include <device_manager.h> 98 99 100 #define SCSI_MAX_CDB_SIZE 16 // max size of cdb 101 #define SCSI_MAX_SENSE_SIZE 64 // max size of sense data 102 #define SCSI_SIM_PRIV 1536 // SIM private data; this may be a bit much but 103 // we currently need that for the compatibility layer 104 105 // bus/device handle 106 typedef struct scsi_bus_info *scsi_bus; 107 typedef struct scsi_device_info *scsi_device; 108 109 110 // structure of one scsi i/o CCB (command control block) 111 typedef struct scsi_ccb 112 { 113 struct scsi_ccb *next, *prev; // internal 114 115 uchar subsys_status; // Returned subsystem status 116 uchar device_status; // Returned scsi device status 117 118 uchar path_id; // Path ID for the request 119 uchar target_id; // Target device ID 120 uchar target_lun; // Target LUN number 121 uint32 flags; // Flags for operation of the subsystem 122 123 // released once after asynchronous execution of request; 124 // initialised by alloc_ccb, can be replaced for action but 125 // must be restored before returning via free_ccb 126 sem_id completion_sem; 127 128 uint8 cdb[SCSI_MAX_CDB_SIZE]; // command data block 129 uchar cdb_len; // length of command in bytes 130 int64 sort; // value of command to sort on (<0 means n/a) 131 bigtime_t timeout; // timeout - 0 = use default 132 133 uchar *data; // pointer to data 134 const physical_entry *sg_list; // SG list 135 uint16 sg_cnt; // number of SG entries 136 uint32 data_len; // length of data 137 int32 data_resid; // data transfer residual length: 2's comp 138 139 uchar sense[SCSI_MAX_SENSE_SIZE]; // autosense data 140 uchar sense_resid; // autosense resid length: 2's comp 141 142 // private 143 bool ordered : 1; // request cannot overtake/be overtaken by others 144 bool buffered : 1; // data is buffered to make it DMA safe 145 bool emulated : 1; // command is executed as part of emulation 146 147 scsi_bus bus; // associated bus 148 scsi_device device; // associated device 149 struct dma_buffer *dma_buffer; // used dma buffer, or NULL 150 uchar state; // bus manager state 151 152 // original data before command emulation was applied 153 uint8 orig_cdb[SCSI_MAX_CDB_SIZE]; 154 uchar orig_cdb_len; 155 const physical_entry *orig_sg_list; 156 uint16 orig_sg_cnt; 157 uint32 orig_data_len; 158 159 // private SIM data 160 uchar sim_state; // set to zero when request is submitted first time 161 uchar sim_priv[SCSI_SIM_PRIV]; /* SIM private data area */ 162 } scsi_ccb; 163 164 165 // Defines for the subsystem status field 166 167 #define SCSI_REQ_INPROG 0x00 /* request is in progress */ 168 #define SCSI_REQ_CMP 0x01 /* request completed w/out error */ 169 #define SCSI_REQ_ABORTED 0x02 /* request aborted by the host */ 170 #define SCSI_UA_ABORT 0x03 /* Unable to Abort request */ 171 #define SCSI_REQ_CMP_ERR 0x04 /* request completed with an err */ 172 #define SCSI_BUSY 0x05 /* subsystem is busy */ 173 #define SCSI_REQ_INVALID 0x06 /* request is invalid */ 174 #define SCSI_PATH_INVALID 0x07 /* Path ID supplied is invalid */ 175 #define SCSI_DEV_NOT_THERE 0x08 /* SCSI device not installed/there */ 176 #define SCSI_UA_TERMIO 0x09 /* Unable to Terminate I/O req */ 177 #define SCSI_SEL_TIMEOUT 0x0A /* Target selection timeout */ 178 #define SCSI_CMD_TIMEOUT 0x0B /* Command timeout */ 179 #define SCSI_MSG_REJECT_REC 0x0D /* Message reject received */ 180 #define SCSI_SCSI_BUS_RESET 0x0E /* SCSI bus reset sent/received */ 181 #define SCSI_UNCOR_PARITY 0x0F /* Uncorrectable parity err occurred */ 182 #define SCSI_AUTOSENSE_FAIL 0x10 /* Autosense: Request sense cmd fail */ 183 #define SCSI_NO_HBA 0x11 /* No HBA detected Error */ 184 #define SCSI_DATA_RUN_ERR 0x12 /* Data overrun/underrun error */ 185 #define SCSI_UNEXP_BUSFREE 0x13 /* Unexpected BUS free */ 186 #define SCSI_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ 187 #define SCSI_PROVIDE_FAIL 0x16 /* Unable to provide requ. capability */ 188 #define SCSI_BDR_SENT 0x17 /* A SCSI BDR msg was sent to target */ 189 #define SCSI_REQ_TERMIO 0x18 /* request terminated by the host */ 190 #define SCSI_HBA_ERR 0x19 /* Unrecoverable host bus adaptor err*/ 191 #define SCSI_BUS_RESET_DENIED 0x1A /* SCSI bus reset denied */ 192 193 #define SCSI_IDE 0x33 /* Initiator Detected Error Received */ 194 #define SCSI_RESRC_UNAVAIL 0x34 /* Resource unavailable */ 195 #define SCSI_UNACKED_EVENT 0x35 /* Unacknowledged event by host */ 196 #define SCSI_LUN_INVALID 0x38 /* LUN supplied is invalid */ 197 #define SCSI_TID_INVALID 0x39 /* Target ID supplied is invalid */ 198 #define SCSI_FUNC_NOTAVAIL 0x3A /* The requ. func is not available */ 199 #define SCSI_NO_NEXUS 0x3B /* Nexus is not established */ 200 #define SCSI_IID_INVALID 0x3C /* The initiator ID is invalid */ 201 #define SCSI_CDB_RECVD 0x3D /* The SCSI CDB has been received */ 202 #define SCSI_LUN_ALLREADY_ENAB 0x3E /* LUN already enabled */ 203 #define SCSI_SCSI_BUSY 0x3F /* SCSI bus busy */ 204 205 #define SCSI_AUTOSNS_VALID 0x80 /* Autosense data valid for target */ 206 207 #define SCSI_SUBSYS_STATUS_MASK 0x3F /* Mask bits for just the status # */ 208 209 210 // Defines for the flags field 211 212 #define SCSI_DIR_RESV 0x00000000 /* Data direction (00: reserved) */ 213 #define SCSI_DIR_IN 0x00000040 /* Data direction (01: DATA IN) */ 214 #define SCSI_DIR_OUT 0x00000080 /* Data direction (10: DATA OUT) */ 215 #define SCSI_DIR_NONE 0x000000C0 /* Data direction (11: no data) */ 216 #define SCSI_DIR_MASK 0x000000C0 217 218 #define SCSI_DIS_AUTOSENSE 0x00000020 /* Disable autosense feature */ 219 #define SCSI_ORDERED_QTAG 0x00000010 // ordered queue (cannot overtake/be overtaken) 220 #define SCSI_DMA_SAFE 0x00000008 // set if data buffer is DMA approved 221 222 #define SCSI_DIS_DISCONNECT 0x00008000 /* Disable disconnect */ 223 #define SCSI_INITIATE_SYNC 0x00004000 /* Attempt Sync data xfer, and SDTR */ 224 #define SCSI_DIS_SYNC 0x00002000 /* Disable sync, go to async */ 225 #define SCSI_ENG_SYNC 0x00000200 /* Flush resid bytes before cmplt */ 226 227 228 // Defines for the Path Inquiry CCB fields 229 230 // flags in hba_inquiry 231 #define SCSI_PI_MDP_ABLE 0x80 /* Supports MDP message */ 232 #define SCSI_PI_WIDE_32 0x40 /* Supports 32 bit wide SCSI */ 233 #define SCSI_PI_WIDE_16 0x20 /* Supports 16 bit wide SCSI */ 234 #define SCSI_PI_SDTR_ABLE 0x10 /* Supports SDTR message */ 235 #define SCSI_PI_TAG_ABLE 0x02 /* Supports tag queue message */ 236 #define SCSI_PI_SOFT_RST 0x01 /* Supports soft reset */ 237 238 // flags in hba_misc 239 #define SCSI_PIM_SCANHILO 0x80 /* Bus scans from ID 7 to ID 0 */ 240 #define SCSI_PIM_NOREMOVE 0x40 /* Removable dev not included in scan */ 241 242 // sizes of inquiry fields 243 #define SCSI_VUHBA 14 /* Vendor Unique HBA length */ 244 #define SCSI_SIM_ID 16 /* ASCII string len for SIM ID */ 245 #define SCSI_HBA_ID 16 /* ASCII string len for HBA ID */ 246 #define SCSI_FAM_ID 16 /* ASCII string len for FAMILY ID */ 247 #define SCSI_TYPE_ID 16 /* ASCII string len for TYPE ID */ 248 #define SCSI_VERS 8 /* ASCII string len for SIM & HBA vers */ 249 250 251 // Path inquiry, extended by BeOS XPT_EXTENDED_PATH_INQ parameters 252 typedef struct 253 { 254 uchar version_num; /* Version number for the SIM/HBA */ 255 uchar hba_inquiry; /* Mimic of INQ byte 7 for the HBA */ 256 uchar hba_misc; /* Misc HBA feature flags */ 257 uint32 sim_priv; /* Size of SIM private data area */ 258 uchar vuhba_flags[SCSI_VUHBA];/* Vendor unique capabilities */ 259 uchar initiator_id; /* ID of the HBA on the SCSI bus */ 260 uint32 hba_queue_size; // size of adapaters command queue 261 char sim_vid[SCSI_SIM_ID]; /* Vendor ID of the SIM */ 262 char hba_vid[SCSI_HBA_ID]; /* Vendor ID of the HBA */ 263 264 char sim_version[SCSI_VERS]; /* SIM version number */ 265 char hba_version[SCSI_VERS]; /* HBA version number */ 266 char controller_family[SCSI_FAM_ID]; /* Controller family */ 267 char controller_type[SCSI_TYPE_ID]; /* Controller type */ 268 } scsi_path_inquiry; 269 270 271 // Device node 272 273 // target (uint8) 274 #define SCSI_DEVICE_TARGET_ID_ITEM "scsi/target_id" 275 // lun (uint8) 276 #define SCSI_DEVICE_TARGET_LUN_ITEM "scsi/target_lun" 277 // node type 278 #define SCSI_DEVICE_TYPE_NAME "scsi/device/v1" 279 // device inquiry data (raw scsi_res_inquiry) 280 #define SCSI_DEVICE_INQUIRY_ITEM "scsi/device_inquiry" 281 // device type (uint8) 282 #define SCSI_DEVICE_TYPE_ITEM "scsi/type" 283 // vendor name (string) 284 #define SCSI_DEVICE_VENDOR_ITEM "scsi/vendor" 285 // product name (string) 286 #define SCSI_DEVICE_PRODUCT_ITEM "scsi/product" 287 // revision (string) 288 #define SCSI_DEVICE_REVISION_ITEM "scsi/revision" 289 290 // directory containing links to peripheral drivers 291 #define SCSI_PERIPHERAL_DRIVERS_DIR "scsi" 292 293 // bus manager device interface for peripheral driver 294 typedef struct scsi_device_interface { 295 driver_module_info info; 296 297 // get CCB 298 // warning: if pool of CCBs is exhausted, this call is delayed until a 299 // CCB is freed, so don't try to allocate more then one CCB at once! 300 scsi_ccb *(*alloc_ccb)(scsi_device device); 301 // free CCB 302 void (*free_ccb)(scsi_ccb *ccb); 303 304 // execute command asynchronously 305 // when it's finished, the semaphore of the ccb is released 306 // you must provide a S/G list if data_len != 0 307 void (*async_io)(scsi_ccb *ccb); 308 // execute command synchronously 309 // you don't need to provide a S/G list nor have to lock data 310 void (*sync_io)(scsi_ccb *ccb); 311 312 // abort request 313 uchar (*abort)(scsi_ccb *ccb_to_abort); 314 // reset device 315 uchar (*reset_device)(scsi_device device); 316 // terminate request 317 uchar (*term_io)(scsi_ccb *ccb_to_terminate); 318 319 status_t (*ioctl)(scsi_device device, uint32 op, void *buffer, size_t length); 320 } scsi_device_interface; 321 322 #define SCSI_DEVICE_MODULE_NAME "bus_managers/scsi/driver/v1" 323 324 325 // Bus node 326 327 // attributes: 328 329 // path (uint8) 330 #define SCSI_BUS_PATH_ID_ITEM "scsi/path_id" 331 // node type 332 #define SCSI_BUS_TYPE_NAME "scsi/bus" 333 334 // SCSI bus node driver. 335 // This interface can be used by peripheral drivers to access the 336 // bus directly. 337 typedef struct scsi_bus_interface { 338 bus_module_info info; 339 340 // get information about host controller 341 uchar (*path_inquiry)(scsi_bus bus, scsi_path_inquiry *inquiry_data); 342 // reset SCSI bus 343 uchar (*reset_bus)(scsi_bus bus); 344 } scsi_bus_interface; 345 346 // name of SCSI bus node driver 347 #define SCSI_BUS_MODULE_NAME "bus_managers/scsi/bus/v1" 348 349 350 // Interface for SIM 351 352 // cookie for dpc 353 typedef struct scsi_dpc_info *scsi_dpc_cookie; 354 355 // Bus manager interface used by SCSI controller drivers. 356 // SCSI controller drivers get this interface passed via their init_device 357 // method. Further, they must specify this driver as their fixed consumer. 358 typedef struct scsi_for_sim_interface { 359 driver_module_info info; 360 361 // put request into wait queue because of overflow 362 // bus_overflow: true - too many bus requests 363 // false - too many device requests 364 // bus/device won't receive requests until cont_sent_bus/cont_send_device 365 // is called or a request is finished via finished(); 366 // to avoid race conditions (reporting a full and a available bus at once) 367 // the SIM should synchronize calls to requeue, resubmit and finished 368 void (*requeue)(scsi_ccb *ccb, bool bus_overflow); 369 // resubmit request ASAP 370 // to be used if execution of request went wrong and must be retried 371 void (*resubmit)(scsi_ccb *ccb); 372 // mark request as being finished 373 // num_requests: number of requests that were handled by device 374 // when the request was sent (read: how full was the device 375 // queue); needed to find out how large the device queue is; 376 // e.g. if three were already running plus this request makes 377 // num_requests=4 378 void (*finished)(scsi_ccb *ccb, uint num_requests); 379 380 // following functions return error on invalid arguments only 381 status_t (*alloc_dpc)(scsi_dpc_cookie *dpc); 382 status_t (*free_dpc)(scsi_dpc_cookie dpc); 383 status_t (*schedule_dpc)(scsi_bus cookie, scsi_dpc_cookie dpc, /*int flags,*/ 384 void (*func)( void * ), void *arg); 385 386 // block entire bus (can be nested) 387 // no more request will be submitted to this bus 388 void (*block_bus)(scsi_bus bus); 389 // unblock entire bus 390 // requests will be submitted to bus ASAP 391 void (*unblock_bus)(scsi_bus bus); 392 // block one device 393 // no more requests will be submitted to this device 394 void (*block_device)(scsi_device device); 395 // unblock device 396 // requests for this device will be submitted ASAP 397 void (*unblock_device)(scsi_device device); 398 399 // terminate bus overflow condition (see "requeue") 400 void (*cont_send_bus)(scsi_bus bus); 401 // terminate device overflow condition (see "requeue") 402 void (*cont_send_device)(scsi_device device); 403 } scsi_for_sim_interface; 404 405 406 #define SCSI_FOR_SIM_MODULE_NAME "bus_managers/scsi/sim/v1" 407 408 409 // SIM Node 410 411 // attributes: 412 413 // node type 414 #define SCSI_SIM_TYPE_NAME "bus/scsi/v1" 415 // controller name (required, string) 416 #define SCSI_DESCRIPTION_CONTROLLER_NAME "controller_name" 417 418 typedef struct scsi_sim_cookie *scsi_sim_cookie; 419 420 // SIM interface 421 // SCSI controller drivers must provide this interface 422 typedef struct scsi_sim_interface { 423 driver_module_info info; 424 425 // execute request 426 void (*scsi_io)( scsi_sim_cookie cookie, scsi_ccb *ccb ); 427 // abort request 428 uchar (*abort)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_abort ); 429 // reset device 430 uchar (*reset_device)( scsi_sim_cookie cookie, uchar target_id, uchar target_lun ); 431 // terminate request 432 uchar (*term_io)( scsi_sim_cookie cookie, scsi_ccb *ccb_to_terminate ); 433 434 // get information about bus 435 uchar (*path_inquiry)( scsi_sim_cookie cookie, scsi_path_inquiry *inquiry_data ); 436 // scan bus 437 // this is called immediately before the SCSI bus manager scans the bus 438 uchar (*scan_bus)( scsi_sim_cookie cookie ); 439 // reset bus 440 uchar (*reset_bus)( scsi_sim_cookie cookie ); 441 442 // get restrictions of one device 443 // (used for non-SCSI transport protocols and bug fixes) 444 void (*get_restrictions)( 445 scsi_sim_cookie cookie, 446 uchar target_id, // target id 447 bool *is_atapi, // set to true if this is an ATAPI device that 448 // needs some commands emulated 449 bool *no_autosense, // set to true if there is no autosense; 450 // the SCSI bus manager will request sense on 451 // SCSI_REQ_CMP_ERR/SCSI_DEVICE_CHECK_CONDITION 452 uint32 *max_blocks ); // maximum number of blocks per transfer if > 0; 453 // used for buggy devices that cannot handle 454 // large transfers (read: ATAPI ZIP drives) 455 456 status_t (*ioctl)(scsi_sim_cookie, uint8 targetID, uint32 op, void *buffer, size_t length); 457 } scsi_sim_interface; 458 459 460 #endif /* _SCSI_BUSMANAGER_H_ */ 461