xref: /haiku/src/add-ons/kernel/busses/scsi/virtio/VirtioSCSIPrivate.h (revision ed4a8e4d11d7972d6fb6f025c108915ad06c73af)
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