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