1 /* 2 * Copyright 1991-1998 by Open Software Foundation, Inc. 3 * All Rights Reserved 4 * 5 * Permission to use, copy, modify, and distribute this software and 6 * its documentation for any purpose and without fee is hereby granted, 7 * provided that the above copyright notice appears in all copies and 8 * that both the copyright notice and this permission notice appear in 9 * supporting documentation. 10 * 11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 /* 22 * MkLinux 23 */ 24 /* CMU_HIST */ 25 /* 26 * Revision 2.12.4.1 92/03/03 16:13:59 jeffreyh 27 * Pick up changes from TRUNK. 28 * [92/02/26 11:01:36 jeffreyh] 29 * 30 * Revision 2.13 92/01/03 20:03:43 dbg 31 * Rename io_lock to io_req_lock to avoid conflict with io_lock 32 * macro for ipc_objects. 33 * [91/10/21 dbg] 34 * 35 * Revision 2.12 91/08/28 11:11:24 jsb 36 * Removed semicolon after decl_simple_lock_data in io_req declaration. 37 * [91/08/16 15:31:22 jsb] 38 * 39 * Add lock and associated macros to io_req structure. 40 * [91/08/12 17:28:46 dlb] 41 * 42 * Add io_total for use by writes - io_count is for each driver 43 * operation, io_total is for the entire device_write. 44 * [91/08/05 17:34:49 dlb] 45 * 46 * Add io_copy field to remember vm_map_copy_t that must be discarded 47 * when a mapped (not inline) device_write completes. 48 * [91/07/31 14:43:07 dlb] 49 * 50 * Revision 2.11 91/08/03 18:17:39 jsb 51 * Added IO_LOANED flag, initially for norma_ipc support. 52 * Loaned ior's are returned directly at interrupt level; 53 * see iodone() for details. 54 * [91/07/27 22:28:29 jsb] 55 * 56 * Revision 2.10 91/05/14 15:58:41 mrt 57 * Correcting copyright 58 * 59 * Revision 2.9 91/05/13 06:02:25 af 60 * Added IO_INTERNAL, for use when an io_request packet is used 61 * just for synchronization purposes. 62 * [91/03/11 af] 63 * 64 * Revision 2.8 91/02/05 17:09:49 mrt 65 * Changed to new Mach copyright 66 * [91/01/31 17:29:53 mrt] 67 * 68 * Revision 2.7 90/06/02 14:48:08 rpd 69 * Converted to new IPC. Removed io_dev_port. 70 * [90/03/26 21:56:39 rpd] 71 * 72 * Revision 2.6 90/05/03 15:19:09 dbg 73 * Add spare flags definition for device-dependent uses. 74 * [90/03/14 dbg] 75 * 76 * Revision 2.5 90/01/11 11:42:13 dbg 77 * De-lint. 78 * [89/12/06 dbg] 79 * 80 * Revision 2.4 89/09/08 11:24:30 dbg 81 * Allocate io_req elements from kalloc pool, to allow a 82 * variable-length vm_page_t array at the end of the io_req_t. 83 * [89/08/14 dbg] 84 * 85 * Changed 'dev_hdr_t' to 'device_t'. 86 * [89/08/01 dbg] 87 * 88 * Revision 2.3 89/08/31 16:18:51 rwd 89 * Added io_inband_zone 90 * [89/08/15 rwd] 91 * 92 * Revision 2.2 89/08/05 16:06:50 rwd 93 * Added IO_INBAND. 94 * [89/08/04 rwd] 95 * 96 * 10-Oct-88 David Golub (dbg) at Carnegie-Mellon University 97 * Created. 98 * 99 */ 100 /* CMU_ENDHIST */ 101 /* 102 * Mach Operating System 103 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University 104 * All Rights Reserved. 105 * 106 * Permission to use, copy, modify and distribute this software and its 107 * documentation is hereby granted, provided that both the copyright 108 * notice and this permission notice appear in all copies of the 109 * software, derivative works or modified versions, and any portions 110 * thereof, and that both notices appear in supporting documentation. 111 * 112 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 113 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 114 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 115 * 116 * Carnegie Mellon requests users of this software to return to 117 * 118 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 119 * School of Computer Science 120 * Carnegie Mellon University 121 * Pittsburgh PA 15213-3890 122 * 123 * any improvements or extensions that they make and grant Carnegie Mellon 124 * the rights to redistribute these changes. 125 */ 126 /* 127 */ 128 /* 129 * Author: David B. Golub, Carnegie Mellon University 130 * Date: 10/88 131 */ 132 133 #ifndef _IO_REQ_ 134 #define _IO_REQ_ 135 136 #include <mach_kdb.h> 137 #include <chained_ios.h> 138 139 #include <mach/boolean.h> 140 #include <mach/port.h> 141 #include <mach/message.h> 142 #include <mach/vm_param.h> 143 #include <kern/kalloc.h> 144 #include <kern/lock.h> 145 #include <vm/vm_page.h> 146 #include <device/device_types.h> 147 #include <device/device_typedefs.h> 148 #include <device/io_scatter.h> 149 150 #include <kern/macro_help.h> 151 152 /* 153 * IO request scatter/gather list 154 */ 155 struct io_sg_entry { /* sg list entry */ 156 vm_offset_t iosge_phys; /* physical address */ 157 vm_size_t iosge_length; /* length in bytes */ 158 }; 159 160 struct io_sglist_hdr { /* sg list header */ 161 vm_size_t length; /* total bytes covered by list */ 162 int nentries; /* number of entries */ 163 }; 164 165 typedef struct io_sglist { /* sg list structure */ 166 struct io_sglist_hdr iosg_hdr; /* list header */ 167 struct io_sg_entry iosg_list[1]; /* variable sized list */ 168 } *io_sglist_t; 169 170 /* 171 * Size of an sglist with n entries 172 */ 173 #define IO_SGLIST_SIZE(n) \ 174 (sizeof(struct io_sglist_hdr) + (n)*sizeof(struct io_sg_entry)) 175 176 /* 177 * IO request element, queued on device for delayed replies. 178 */ 179 struct io_req { 180 struct io_req * io_next; /* next, ... */ 181 struct io_req * io_prev; /* prev pointers: link in done, 182 defered, or in-progress list */ 183 mach_device_t io_device; /* pointer to open-device structure */ 184 char * io_dev_ptr; /* pointer to driver structure - 185 filled in by driver if necessary */ 186 int io_unit; /* unit number ('minor') of device */ 187 int io_op; /* IO operation */ 188 dev_mode_t io_mode; /* operation mode (wait, truncate) */ 189 recnum_t io_recnum; /* starting record number for 190 random-access devices */ 191 192 union io_un { 193 io_buf_ptr_t data; /* data, for IO requests */ 194 } io_un; 195 #define io_data io_un.data 196 197 union io_seg { 198 io_sglist_t sgp; /* sglist, for IO requests */ 199 unsigned seg_count; /* Chained IOs seg count */ 200 } io_seg; 201 #define io_sgp io_seg.sgp 202 #define io_seg_count io_seg.seg_count 203 204 vm_address_t io_uaddr; /* user buf for overwrite requests */ 205 vm_map_t io_map; /* target map for overwrite requests */ 206 io_buf_len_t io_count; /* amount requested */ 207 io_buf_len_t io_alloc_size; /* amount allocated */ 208 io_buf_len_t io_residual; /* amount NOT done */ 209 io_return_t io_error; /* error code */ 210 boolean_t (*io_done)( /* call when done - returns TRUE 211 if IO really finished */ 212 io_req_t ior); 213 struct ipc_port *io_reply_port; /* reply port/queue, for asynchronous 214 messages */ 215 mach_msg_type_name_t io_reply_port_type; 216 /* send or send-once right? */ 217 struct io_req * io_link; /* forward link (for driver header) */ 218 struct io_req * io_rlink; /* reverse link (for driver header) */ 219 vm_map_copy_t io_copy; /* vm_map_copy obj. for this op. */ 220 /* Lock for this structure */ 221 #if MACH_KDB 222 int io_ioip; 223 #endif 224 io_buf_len_t io_total; /* total op size, for write */ 225 int io_save; /* Saved IO operation */ 226 decl_simple_lock_data(,io_req_lock) /* Lock for this structure */ 227 }; 228 229 230 /* 231 * LOCKING NOTE: Operations on io_req's are in general single threaded by 232 * the invoking code, obviating the need for a lock. The usual IO_CALL 233 * path through the code is: Initiating thread hands io_req to device driver, 234 * driver passes it to io_done thread, io_done thread sends reply message. No 235 * locking is needed in this sequence. Unfortunately, a synchronous wait 236 * for a buffer requires a lock to avoid problems if the wait and interrupt 237 * happen simultaneously on different processors. 238 */ 239 240 #define ior_lock(ior) simple_lock(&(ior)->io_req_lock) 241 #define ior_unlock(ior) simple_unlock(&(ior)->io_req_lock) 242 243 /* 244 * Flags and operations 245 */ 246 247 #define IO_WRITE 0x00000000 /* operation is write */ 248 #define IO_READ 0x00000001 /* operation is read */ 249 #define IO_OPEN 0x00000002 /* operation is open */ 250 #define IO_DONE 0x00000100 /* operation complete */ 251 #define IO_ERROR 0x00000200 /* error on operation */ 252 #define IO_BUSY 0x00000400 /* operation in progress */ 253 #define IO_WANTED 0x00000800 /* wakeup when no longer BUSY */ 254 #define IO_BAD 0x00001000 /* bad disk block */ 255 #define IO_CALL 0x00002000 /* call io_done_thread when done */ 256 #define IO_INBAND 0x00004000 /* mig call was inband */ 257 #define IO_INTERNAL 0x00008000 /* internal, device-driver specific */ 258 #define IO_LOANED 0x00010000 /* ior loaned by another module */ 259 #define IO_SYNC 0x00020000 /* caller is synchronous */ 260 #define IO_OVERWRITE 0x00040000 /* overwrite request */ 261 #define IO_KERNEL_BUF 0x00080000 /* buffer address is in kernel */ 262 #define IO_QUEUE 0x00100000 /* use completion queue when done */ 263 #define IO_SGLIST 0x00200000 /* data points to scatter/gather list*/ 264 #define IO_TRANSPORT 0x00400000 /* Special IOR from transport */ 265 #define IO_PASSIVE 0x00800000 /* Post target mode request */ 266 #define IO_SCATTER 0x01000000 /* io_data points to io_scatter */ 267 #define IO_PAD 0x02000000 /* This is a padded IO and we 268 don't care as much about residual */ 269 #define IO_HANDOFF 0x04000000 /* ior moved from user io_done_queue to 270 io_done_thread_queue */ 271 #define IO_FREE 0x08000000 /* ior can be freed now */ 272 #define IO_WCLONED 0x10000000 /* caller recycled written data */ 273 #define IO_SPARE_START 0x20000000 /* start of spare flags */ 274 #define IO_CHAINED 0x40000000 /* Chained io. This means that several 275 IO requests are chained with this 276 one. A single I/O operation will 277 performed for the complete chain. 278 It is mostly used to gather disk 279 IOs on contiguous disk blocks. 280 Not te be mixed up with IO_SGLIST */ 281 282 extern io_return_t block_io( 283 void (*strat)(io_req_t ior), 284 void (*max_count)(io_req_t ior), 285 io_req_t ior); 286 extern void disksort( 287 io_req_t head, 288 io_req_t ior); 289 extern vm_offset_t block_io_mmap(dev_t, vm_offset_t, vm_prot_t); 290 291 zone_t io_req_zone; 292 293 /* 294 * Macros to allocate and free IORs 295 */ 296 #if MACH_KDB 297 #define io_req_alloc(ior) \ 298 MACRO_BEGIN \ 299 (ior) = (io_req_t)zalloc(io_req_zone); \ 300 simple_lock_init(&(ior)->io_req_lock, ETAP_IO_REQ); \ 301 ior->io_ioip = 0;\ 302 MACRO_END 303 304 #define io_req_free(ior) \ 305 MACRO_BEGIN \ 306 assert(!ior->io_ioip); \ 307 zfree(io_req_zone, (vm_offset_t)(ior)); \ 308 MACRO_END 309 310 #else 311 #define io_req_alloc(ior) \ 312 MACRO_BEGIN \ 313 (ior) = (io_req_t)zalloc(io_req_zone); \ 314 simple_lock_init(&(ior)->io_req_lock, ETAP_IO_REQ); \ 315 MACRO_END 316 317 #define io_req_free(ior) \ 318 MACRO_BEGIN \ 319 zfree(io_req_zone, (vm_offset_t)(ior)); \ 320 MACRO_END 321 #endif 322 323 #define io_sglist_alloc(sglist, nentries) \ 324 MACRO_BEGIN \ 325 (sglist) = (io_sglist_t)kalloc(IO_SGLIST_SIZE(nentries));\ 326 (sglist)->iosg_hdr.nentries = (nentries); \ 327 MACRO_END 328 329 #define io_sglist_free(sglist) \ 330 (kfree((vm_offset_t)(sglist), \ 331 IO_SGLIST_SIZE((sglist)->iosg_hdr.nentries))) 332 333 zone_t io_inband_zone; /* for inband reads */ 334 335 #if CHAINED_IOS 336 337 extern void chain_io_reqs(io_req_t ior1, 338 io_req_t ior2, 339 io_req_t head); 340 341 extern void chained_iodone(io_req_t ior); 342 343 extern void split_io_reqs(io_req_t ior); 344 345 #endif /* CHAINED_IOS */ 346 347 #endif /* _IO_REQ_ */ 348