vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / bus_managers / scsi / queuing.h
blob03efedfab92341fad45e622e4f40764bdd4e871a
1 /*
2 ** Copyright 2002/03, Thomas Kurschel. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
6 /*
7 Part of Open SCSI bus manager
9 Handling of bus/device blocking. Inline functions defined
10 here don't wake service thread if required and don't lock bus, so
11 everyone using them must take care of that himself.
14 #ifndef __BLOCKING_H__
15 #define __BLOCKING_H__
17 #include "dl_list.h"
19 void scsi_add_queued_request( scsi_ccb *request );
20 void scsi_add_queued_request_first( scsi_ccb *request );
21 void scsi_remove_queued_request( scsi_ccb *request );
24 static inline void scsi_add_req_queue_first( scsi_ccb *request )
26 scsi_device_info *device = request->device;
28 SHOW_FLOW( 3, "request=%p", request );
30 ADD_CDL_LIST_HEAD( request, scsi_ccb, device->queued_reqs, );
33 static inline void scsi_add_req_queue_last( scsi_ccb *request )
35 scsi_device_info *device = request->device;
37 SHOW_FLOW( 3, "request=%p", request );
39 ADD_CDL_LIST_TAIL( request, scsi_ccb, device->queued_reqs, );
42 static inline void scsi_remove_req_queue( scsi_ccb *request )
44 scsi_device_info *device = request->device;
46 SHOW_FLOW( 3, "request=%p", request );
48 REMOVE_CDL_LIST( request, device->queued_reqs, );
51 // ignored, if device is already queued
52 static inline void scsi_add_device_queue_first( scsi_device_info *device )
54 SHOW_FLOW0( 3, "" );
56 if( DEVICE_IN_WAIT_QUEUE( device ))
57 return;
59 SHOW_FLOW0( 3, "was not in wait queue - adding" );
61 ADD_CDL_LIST_HEAD( device, scsi_device_info, device->bus->waiting_devices, waiting_ );
64 // ignored, if device is already queued
65 static inline void scsi_add_device_queue_last( scsi_device_info *device )
67 SHOW_FLOW0( 3, "" );
69 if( DEVICE_IN_WAIT_QUEUE( device ))
70 return;
72 SHOW_FLOW0( 3, "was not in wait queue - adding" );
74 ADD_CDL_LIST_TAIL( device, scsi_device_info, device->bus->waiting_devices, waiting_ );
77 // ignored, if device is not in queue
78 static inline void scsi_remove_device_queue( scsi_device_info *device )
80 SHOW_FLOW0( 3, "" );
82 if( !DEVICE_IN_WAIT_QUEUE( device ))
83 return;
85 SHOW_FLOW0( 3, "was in wait queue - removing from it" );
87 REMOVE_CDL_LIST( device, device->bus->waiting_devices, waiting_ );
89 // reset next link so we can see that it's not in device queue
90 device->waiting_next = NULL;
93 // set overflow bit of device; this will not remove device from bus queue!
94 // (multiple calls are ignored gracefully)
95 static inline void scsi_set_device_overflow( scsi_device_info *device )
97 device->lock_count += device->sim_overflow ^ 1;
98 device->sim_overflow = 1;
101 // set overflow bit of bus
102 // (multiple calls are ignored gracefully)
103 static inline void scsi_set_bus_overflow( scsi_bus_info *bus )
105 bus->lock_count += bus->sim_overflow ^ 1;
106 bus->sim_overflow = 1;
109 // clear overflow bit of device; this will not add device to bus queue!
110 // (multiple calls are ignored gracefully)
111 static inline void scsi_clear_device_overflow( scsi_device_info *device )
113 device->lock_count -= device->sim_overflow;
114 device->sim_overflow = 0;
117 // clear overflow bit of bus
118 // (multiple calls are ignored gracefully)
119 static inline void scsi_clear_bus_overflow( scsi_bus_info *bus )
121 bus->lock_count -= bus->sim_overflow;
122 bus->sim_overflow = 0;
125 // check whether bus has some pending requests it can process now
126 static inline bool scsi_can_service_bus( scsi_bus_info *bus )
128 // bus must not be blocked and requests pending
129 return (bus->lock_count == 0) & (bus->waiting_devices != NULL);
132 // unblock bus
133 // lock must be hold; service thread is not informed
134 static inline void scsi_unblock_bus_noresume( scsi_bus_info *bus, bool by_SIM )
136 if( bus->blocked[by_SIM] > 0 ) {
137 --bus->blocked[by_SIM];
138 --bus->lock_count;
139 } else {
140 panic( "Tried to unblock bus %d which wasn't blocked",
141 bus->path_id );
146 // unblock device
147 // lock must be hold; device is not added to queue and service thread is not informed
148 static inline void scsi_unblock_device_noresume( scsi_device_info *device, bool by_SIM )
150 if( device->blocked[by_SIM] > 0 ) {
151 --device->blocked[by_SIM];
152 --device->lock_count;
153 } else {
154 panic( "Tried to unblock device %d/%d/%d which wasn't blocked",
155 device->bus->path_id, device->target_id, device->target_lun );
160 // block bus
161 // lock must be hold
162 static inline void scsi_block_bus_nolock( scsi_bus_info *bus, bool by_SIM )
164 ++bus->blocked[by_SIM];
165 ++bus->lock_count;
169 // block device
170 // lock must be hold
171 static inline void scsi_block_device_nolock( scsi_device_info *device, bool by_SIM )
173 ++device->blocked[by_SIM];
174 ++device->lock_count;
176 // remove device from bus queue as it cannot be processed anymore
177 scsi_remove_device_queue( device );
181 void scsi_block_bus( scsi_bus_info *bus );
182 void scsi_unblock_bus( scsi_bus_info *bus );
183 void scsi_block_device( scsi_device_info *device );
184 void scsi_unblock_device( scsi_device_info *device );
186 void scsi_cont_send_bus( scsi_bus_info *bus );
187 void scsi_cont_send_device( scsi_device_info *device );
189 #endif