1 /* 2 * Copyright 2004-2013, Haiku, Inc. All Rights Reserved. 3 * Copyright 2002, Thomas Kurschel. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 #ifndef __SCSI_PERIPH_INT_H__ 7 #define __SCSI_PERIPH_INT_H__ 8 9 10 #include <stddef.h> 11 12 #include <scsi_periph.h> 13 #include <device_manager.h> 14 15 #include "IORequest.h" 16 #include "wrapper.h" 17 18 19 enum trim_command { 20 TRIM_NONE, // TRIM operation is disabled for this device 21 TRIM_UNMAP, // UNMAP command wil be used 22 TRIM_WRITESAME10, // WRITE SAME (10) with UNMAP bit enabled will be used 23 TRIM_WRITESAME16 // WRITE SAME (16) with UNMAP bit enabled will be used 24 }; 25 26 27 typedef struct scsi_periph_device_info { 28 struct scsi_periph_handle_info *handles; 29 30 ::scsi_device scsi_device; 31 scsi_device_interface *scsi; 32 periph_device_cookie periph_device; 33 device_node *node; 34 35 bool removal_requested; 36 37 bool removable; // true, if device is removable 38 39 enum trim_command unmap_command; // command to be used to discard free blocks 40 uint32 max_unmap_lba_count; // max. number of LBAs in one command 41 uint32 max_unmap_descriptor_count; // max. number of ranges in one command 42 43 uint32 block_size; 44 int32 preferred_ccb_size; 45 int32 rw10_enabled; // 10 byte r/w commands supported; access must be atomic 46 int32 next_tag_action; // queuing flag for next r/w command; access must be atomic 47 48 struct mutex mutex; 49 int std_timeout; 50 51 scsi_periph_callbacks *callbacks; 52 } scsi_periph_device_info; 53 54 typedef struct scsi_periph_handle_info { 55 scsi_periph_device_info *device; 56 struct scsi_periph_handle_info *next, *prev; 57 58 int pending_error; // error to be reported on all accesses 59 // (used to block access after medium change until 60 // B_GET_MEDIA_STATUS is called) 61 periph_handle_cookie periph_handle; 62 } scsi_periph_handle_info; 63 64 extern device_manager_info *gDeviceManager; 65 66 67 // removable.c 68 69 void periph_media_changed(scsi_periph_device_info *device, scsi_ccb *ccb); 70 void periph_media_changed_public(scsi_periph_device_info *device); 71 status_t periph_get_media_status(scsi_periph_handle_info *handle); 72 err_res periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request, 73 bool start, bool with_LoEj); 74 75 76 // error_handling.c 77 78 err_res periph_check_error(scsi_periph_device_info *device, scsi_ccb *request); 79 80 81 // handle.c 82 83 status_t periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle, 84 scsi_periph_handle_info **res_handle); 85 status_t periph_handle_close(scsi_periph_handle_info *handle); 86 status_t periph_handle_free(scsi_periph_handle_info *handle); 87 88 89 // block.c 90 91 status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb); 92 status_t periph_trim_device(scsi_periph_device_info *device, scsi_ccb *request, 93 scsi_block_range* ranges, uint32 rangeCount, uint64* trimmedBlocks); 94 95 96 // device.c 97 98 status_t periph_register_device(periph_device_cookie periph_device, 99 scsi_periph_callbacks *callbacks, scsi_device scsi_device, 100 scsi_device_interface *scsi, device_node *node, bool removable, 101 int preferredCcbSize, scsi_periph_device *driver); 102 status_t periph_unregister_device(scsi_periph_device_info *driver); 103 char *periph_compose_device_name(device_node *device_node, const char *prefix); 104 105 106 // io.c 107 108 status_t periph_read_write(scsi_periph_device_info *device, scsi_ccb *request, 109 uint64 offset, size_t numBlocks, physical_entry* vecs, size_t vecCount, 110 bool isWrite, size_t* _bytesTransferred); 111 status_t periph_io(scsi_periph_device_info* device, io_operation* operation, 112 size_t *_bytesTransferred); 113 status_t periph_ioctl(scsi_periph_handle_info *handle, int op, 114 void *buf, size_t len); 115 void periph_sync_queue_daemon(void *arg, int iteration); 116 status_t vpd_page_get(scsi_periph_device_info *device, scsi_ccb* request, 117 uint8 page, void* data, uint16 length); 118 119 120 // scsi_periph.c 121 122 status_t periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request); 123 status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb, 124 uchar cdb_len, void *data, size_t data_len, int ccb_flags); 125 126 127 // sync.c 128 129 err_res periph_synchronize_cache(scsi_periph_device_info *device, 130 scsi_ccb *request); 131 132 #endif /* __SCSI_PERIPH_INT_H__ */ 133