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