182fda49eSJérôme Duval /* 282fda49eSJérôme Duval * Copyright 2013, Jérôme Duval, korli@users.berlios.de. 382fda49eSJérôme Duval * Distributed under the terms of the MIT License. 482fda49eSJérôme Duval */ 582fda49eSJérôme Duval #ifndef VIRTIO_SCSI_PRIVATE_H 682fda49eSJérôme Duval #define VIRTIO_SCSI_PRIVATE_H 782fda49eSJérôme Duval 882fda49eSJérôme Duval 982fda49eSJérôme Duval #include <bus/SCSI.h> 1082fda49eSJérôme Duval #include <condition_variable.h> 1182fda49eSJérôme Duval #include <lock.h> 1282fda49eSJérôme Duval #include <scsi_cmds.h> 1382fda49eSJérôme Duval #include <virtio.h> 1482fda49eSJérôme Duval 1582fda49eSJérôme Duval #include "virtio_scsi.h" 1682fda49eSJérôme Duval 1782fda49eSJérôme Duval 1882fda49eSJérôme Duval //#define TRACE_VIRTIO_SCSI 1982fda49eSJérôme Duval #ifdef TRACE_VIRTIO_SCSI 2082fda49eSJérôme Duval # define TRACE(x...) dprintf("virtio_scsi: " x) 2182fda49eSJérôme Duval #else 2282fda49eSJérôme Duval # define TRACE(x...) ; 2382fda49eSJérôme Duval #endif 2482fda49eSJérôme Duval #define ERROR(x...) dprintf("\33[33mvirtio_scsi:\33[0m " x) 2582fda49eSJérôme Duval #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 2682fda49eSJérôme Duval 2782fda49eSJérôme Duval extern device_manager_info* gDeviceManager; 2882fda49eSJérôme Duval extern scsi_for_sim_interface *gSCSI; 2982fda49eSJérôme Duval 3082fda49eSJérôme Duval bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, 3182fda49eSJérôme Duval void *buffer, int size, bool toBuffer); 3282fda49eSJérôme Duval void swap_words(void *data, size_t size); 3382fda49eSJérôme Duval 3482fda49eSJérôme Duval 3582fda49eSJérôme Duval #define VIRTIO_SCSI_STANDARD_TIMEOUT 10 * 1000 * 1000 3682fda49eSJérôme Duval #define VIRTIO_SCSI_INITIATOR_ID 7 3782fda49eSJérôme Duval 3882fda49eSJérôme Duval 3982fda49eSJérôme Duval class VirtioSCSIRequest; 4082fda49eSJérôme Duval 4182fda49eSJérôme Duval 4282fda49eSJérôme Duval class VirtioSCSIController { 4382fda49eSJérôme Duval public: 4482fda49eSJérôme Duval VirtioSCSIController(device_node* node); 4582fda49eSJérôme Duval ~VirtioSCSIController(); 4682fda49eSJérôme Duval 4782fda49eSJérôme Duval status_t InitCheck(); 4882fda49eSJérôme Duval 4982fda49eSJérôme Duval void SetBus(scsi_bus bus); 5082fda49eSJérôme Duval scsi_bus Bus() const { return fBus; } 5182fda49eSJérôme Duval 5282fda49eSJérôme Duval void PathInquiry(scsi_path_inquiry* info); 5382fda49eSJérôme Duval void GetRestrictions(uint8 targetID, bool* isATAPI, 5482fda49eSJérôme Duval bool* noAutoSense, uint32* maxBlocks); 5582fda49eSJérôme Duval uchar ResetDevice(uchar targetID, uchar targetLUN); 5682fda49eSJérôme Duval status_t ExecuteRequest(scsi_ccb* request); 5782fda49eSJérôme Duval uchar AbortRequest(scsi_ccb* request); 5882fda49eSJérôme Duval uchar TerminateRequest(scsi_ccb* request); 5982fda49eSJérôme Duval status_t Control(uint8 targetID, uint32 op, 6082fda49eSJérôme Duval void* buffer, size_t length); 6182fda49eSJérôme Duval 6282fda49eSJérôme Duval private: 63*ed4a8e4dSJérôme Duval static void _RequestCallback(void* driverCookie, 64*ed4a8e4dSJérôme Duval void *cookie); 65*ed4a8e4dSJérôme Duval void _RequestInterrupt(); 6682fda49eSJérôme Duval 6782fda49eSJérôme Duval device_node* fNode; 6882fda49eSJérôme Duval scsi_bus fBus; 6982fda49eSJérôme Duval 7082fda49eSJérôme Duval virtio_device_interface* fVirtio; 7182fda49eSJérôme Duval virtio_device* fVirtioDevice; 7282fda49eSJérôme Duval 7382fda49eSJérôme Duval status_t fStatus; 7482fda49eSJérôme Duval struct virtio_scsi_config fConfig; 7582fda49eSJérôme Duval uint32 fFeatures; 7682fda49eSJérôme Duval ::virtio_queue fControlVirtioQueue; 7782fda49eSJérôme Duval ::virtio_queue fEventVirtioQueue; 7882fda49eSJérôme Duval ::virtio_queue fRequestVirtioQueue; 7982fda49eSJérôme Duval 8082fda49eSJérôme Duval area_id fArea; 8182fda49eSJérôme Duval struct virtio_scsi_event* fEvents; 8282fda49eSJérôme Duval 8382fda49eSJérôme Duval VirtioSCSIRequest* fRequest; 8482fda49eSJérôme Duval 8582fda49eSJérôme Duval spinlock fInterruptLock; 8682fda49eSJérôme Duval ConditionVariable fInterruptCondition; 8782fda49eSJérôme Duval ConditionVariableEntry fInterruptConditionEntry; 8882fda49eSJérôme Duval bool fExpectsInterrupt; 8982fda49eSJérôme Duval 9082fda49eSJérôme Duval }; 9182fda49eSJérôme Duval 9282fda49eSJérôme Duval 9382fda49eSJérôme Duval class VirtioSCSIRequest { 9482fda49eSJérôme Duval public: 9582fda49eSJérôme Duval VirtioSCSIRequest(bool hasLock); 9682fda49eSJérôme Duval ~VirtioSCSIRequest(); 9782fda49eSJérôme Duval 9882fda49eSJérôme Duval void SetStatus(uint8 status); 9982fda49eSJérôme Duval uint8 Status() const { return fStatus; } 10082fda49eSJérôme Duval 10182fda49eSJérôme Duval void SetTimeout(bigtime_t timeout); 10282fda49eSJérôme Duval bigtime_t Timeout() const { return fTimeout; } 10382fda49eSJérôme Duval 10482fda49eSJérôme Duval bool HasSense() { 10582fda49eSJérôme Duval return (fResponse->sense_len > 0); } 10682fda49eSJérôme Duval 10782fda49eSJérôme Duval void SetIsWrite(bool isWrite); 10882fda49eSJérôme Duval bool IsWrite() const { return fIsWrite; } 10982fda49eSJérôme Duval 11082fda49eSJérôme Duval void SetBytesLeft(uint32 bytesLeft); 11182fda49eSJérôme Duval size_t* BytesLeft() { return &fBytesLeft; } 11282fda49eSJérôme Duval 11382fda49eSJérôme Duval bool HasData() const 11482fda49eSJérôme Duval { return fCCB->data_length > 0; } 11582fda49eSJérôme Duval 11682fda49eSJérôme Duval status_t Finish(bool resubmit); 11782fda49eSJérôme Duval 11882fda49eSJérôme Duval // SCSI stuff 11982fda49eSJérôme Duval status_t Start(scsi_ccb *ccb); 12082fda49eSJérôme Duval scsi_ccb* CCB() { return fCCB; } 12182fda49eSJérôme Duval 12282fda49eSJérôme Duval void RequestSense(); 12382fda49eSJérôme Duval 12482fda49eSJérôme Duval void FillRequest(uint32 inCount, uint32 outCount, 12582fda49eSJérôme Duval physical_entry *entries); 12682fda49eSJérôme Duval 12782fda49eSJérôme Duval private: 12882fda49eSJérôme Duval void _FillSense(scsi_sense *sense); 12982fda49eSJérôme Duval uchar _ResponseStatus(); 13082fda49eSJérôme Duval 13182fda49eSJérôme Duval mutex fLock; 13282fda49eSJérôme Duval bool fHasLock; 13382fda49eSJérôme Duval 13482fda49eSJérôme Duval uint8 fStatus; 13582fda49eSJérôme Duval 13682fda49eSJérôme Duval bigtime_t fTimeout; 13782fda49eSJérôme Duval size_t fBytesLeft; 13882fda49eSJérôme Duval bool fIsWrite; 13982fda49eSJérôme Duval scsi_ccb* fCCB; 14082fda49eSJérôme Duval 14182fda49eSJérôme Duval // virtio scsi 14282fda49eSJérôme Duval void* fBuffer; 14382fda49eSJérôme Duval struct virtio_scsi_cmd_req *fRequest; 14482fda49eSJérôme Duval struct virtio_scsi_cmd_resp *fResponse; 14582fda49eSJérôme Duval }; 14682fda49eSJérôme Duval 14782fda49eSJérôme Duval 14882fda49eSJérôme Duval #endif // VIRTIO_SCSI_PRIVATE_H 14982fda49eSJérôme Duval 150