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 97 scsi_dpc_cookie fEventDPC; 98 struct virtio_scsi_event fEventBuffers[VIRTIO_SCSI_NUM_EVENTS]; 99 }; 100 101 102 class VirtioSCSIRequest { 103 public: 104 VirtioSCSIRequest(bool hasLock); 105 ~VirtioSCSIRequest(); 106 107 void SetStatus(uint8 status); 108 uint8 Status() const { return fStatus; } 109 110 void SetTimeout(bigtime_t timeout); 111 bigtime_t Timeout() const { return fTimeout; } 112 113 bool HasSense() { 114 return (fResponse->sense_len > 0); } 115 116 void SetIsWrite(bool isWrite); 117 bool IsWrite() const { return fIsWrite; } 118 119 void SetBytesLeft(uint32 bytesLeft); 120 size_t* BytesLeft() { return &fBytesLeft; } 121 122 bool HasData() const 123 { return fCCB->data_length > 0; } 124 125 status_t Finish(bool resubmit); 126 void Abort(); 127 128 // SCSI stuff 129 status_t Start(scsi_ccb *ccb); 130 scsi_ccb* CCB() { return fCCB; } 131 132 void RequestSense(); 133 134 void FillRequest(uint32 inCount, uint32 outCount, 135 physical_entry *entries); 136 137 private: 138 void _FillSense(scsi_sense *sense); 139 uchar _ResponseStatus(); 140 141 mutex fLock; 142 bool fHasLock; 143 144 uint8 fStatus; 145 146 bigtime_t fTimeout; 147 size_t fBytesLeft; 148 bool fIsWrite; 149 scsi_ccb* fCCB; 150 151 // virtio scsi 152 void* fBuffer; 153 struct virtio_scsi_cmd_req *fRequest; 154 struct virtio_scsi_cmd_resp *fResponse; 155 }; 156 157 158 #endif // VIRTIO_SCSI_PRIVATE_H 159 160