1 /* 2 * Copyright 2013, Jérôme Duval, korli@users.berlios.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef VIRTIO_SCSI_PRIVATE_H 6 #define VIRTIO_SCSI_PRIVATE_H 7 8 9 #include <bus/SCSI.h> 10 #include <condition_variable.h> 11 #include <lock.h> 12 #include <scsi_cmds.h> 13 #include <virtio.h> 14 15 #include "virtio_scsi.h" 16 17 18 //#define TRACE_VIRTIO_SCSI 19 #ifdef TRACE_VIRTIO_SCSI 20 # define TRACE(x...) dprintf("virtio_scsi: " x) 21 #else 22 # define TRACE(x...) ; 23 #endif 24 #define ERROR(x...) dprintf("\33[33mvirtio_scsi:\33[0m " x) 25 #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 26 27 extern device_manager_info* gDeviceManager; 28 extern scsi_for_sim_interface *gSCSI; 29 30 bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, 31 void *buffer, int size, bool toBuffer); 32 void swap_words(void *data, size_t size); 33 34 35 #define VIRTIO_SCSI_STANDARD_TIMEOUT 10 * 1000 * 1000 36 #define VIRTIO_SCSI_INITIATOR_ID 7 37 38 #define VIRTIO_SCSI_NUM_EVENTS 4 39 40 41 class VirtioSCSIRequest; 42 43 44 class VirtioSCSIController { 45 public: 46 VirtioSCSIController(device_node* node); 47 ~VirtioSCSIController(); 48 49 status_t InitCheck(); 50 51 void SetBus(scsi_bus bus); 52 scsi_bus Bus() const { return fBus; } 53 54 void PathInquiry(scsi_path_inquiry* info); 55 void GetRestrictions(uint8 targetID, bool* isATAPI, 56 bool* noAutoSense, uint32* maxBlocks); 57 uchar ResetDevice(uchar targetID, uchar targetLUN); 58 status_t ExecuteRequest(scsi_ccb* request); 59 uchar AbortRequest(scsi_ccb* request); 60 uchar TerminateRequest(scsi_ccb* request); 61 status_t Control(uint8 targetID, uint32 op, 62 void* buffer, size_t length); 63 64 private: 65 static void _RequestCallback(void* driverCookie, 66 void *cookie); 67 void _RequestInterrupt(); 68 static void _EventCallback(void *driverCookie, 69 void *cookie); 70 void _EventInterrupt( 71 struct virtio_scsi_event* event); 72 static void _RescanChildBus(void *cookie); 73 74 void _SubmitEvent(uint32 event); 75 76 device_node* fNode; 77 scsi_bus fBus; 78 79 virtio_device_interface* fVirtio; 80 virtio_device* fVirtioDevice; 81 82 status_t fStatus; 83 struct virtio_scsi_config fConfig; 84 uint64 fFeatures; 85 ::virtio_queue fControlVirtioQueue; 86 ::virtio_queue fEventVirtioQueue; 87 ::virtio_queue fRequestVirtioQueue; 88 89 area_id fArea; 90 struct virtio_scsi_event* fEvents; 91 92 VirtioSCSIRequest* fRequest; 93 94 int32 fCurrentRequest; 95 ConditionVariable fInterruptCondition; 96 ConditionVariableEntry fInterruptConditionEntry; 97 98 scsi_dpc_cookie fEventDPC; 99 struct virtio_scsi_event fEventBuffers[VIRTIO_SCSI_NUM_EVENTS]; 100 }; 101 102 103 class VirtioSCSIRequest { 104 public: 105 VirtioSCSIRequest(bool hasLock); 106 ~VirtioSCSIRequest(); 107 108 void SetStatus(uint8 status); 109 uint8 Status() const { return fStatus; } 110 111 void SetTimeout(bigtime_t timeout); 112 bigtime_t Timeout() const { return fTimeout; } 113 114 bool HasSense() { 115 return (fResponse->sense_len > 0); } 116 117 void SetIsWrite(bool isWrite); 118 bool IsWrite() const { return fIsWrite; } 119 120 void SetBytesLeft(uint32 bytesLeft); 121 size_t* BytesLeft() { return &fBytesLeft; } 122 123 bool HasData() const 124 { return fCCB->data_length > 0; } 125 126 status_t Finish(bool resubmit); 127 void Abort(); 128 129 // SCSI stuff 130 status_t Start(scsi_ccb *ccb); 131 scsi_ccb* CCB() { return fCCB; } 132 133 void RequestSense(); 134 135 void FillRequest(uint32 inCount, uint32 outCount, 136 physical_entry *entries); 137 138 private: 139 void _FillSense(scsi_sense *sense); 140 uchar _ResponseStatus(); 141 142 mutex fLock; 143 bool fHasLock; 144 145 uint8 fStatus; 146 147 bigtime_t fTimeout; 148 size_t fBytesLeft; 149 bool fIsWrite; 150 scsi_ccb* fCCB; 151 152 // virtio scsi 153 void* fBuffer; 154 struct virtio_scsi_cmd_req *fRequest; 155 struct virtio_scsi_cmd_resp *fResponse; 156 }; 157 158 159 #endif // VIRTIO_SCSI_PRIVATE_H 160 161