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