|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * Author: David B. Golub, Carnegie Mellon University ! 28: * Date: 7/89 ! 29: * ! 30: * Block IO driven from generic kernel IO interface. ! 31: */ ! 32: #include <mach/kern_return.h> ! 33: ! 34: #include <device/param.h> ! 35: #include <device/device_types.h> ! 36: #include <device/io_req.h> ! 37: #include <device/ds_routines.h> ! 38: ! 39: ! 40: ! 41: io_return_t block_io(strat, max_count, ior) ! 42: void (*strat)(); ! 43: void (*max_count)(); ! 44: register io_req_t ior; ! 45: { ! 46: register kern_return_t rc; ! 47: boolean_t wait = FALSE; ! 48: ! 49: /* ! 50: * Make sure the size is not too large by letting max_count ! 51: * change io_count. If we are doing a write, then io_alloc_size ! 52: * preserves the original io_count. ! 53: */ ! 54: (*max_count)(ior); ! 55: ! 56: /* ! 57: * If reading, allocate memory. If writing, wire ! 58: * down the incoming memory. ! 59: */ ! 60: if (ior->io_op & IO_READ) ! 61: rc = device_read_alloc(ior, (vm_size_t)ior->io_count); ! 62: else ! 63: rc = device_write_get(ior, &wait); ! 64: ! 65: if (rc != KERN_SUCCESS) ! 66: return (rc); ! 67: ! 68: /* ! 69: * Queue the operation for the device. ! 70: */ ! 71: (*strat)(ior); ! 72: ! 73: /* ! 74: * The io is now queued. Wait for it if needed. ! 75: */ ! 76: if (wait) { ! 77: iowait(ior); ! 78: return(D_SUCCESS); ! 79: } ! 80: ! 81: return (D_IO_QUEUED); ! 82: } ! 83: ! 84: /* ! 85: * 'standard' max_count routine. VM continuations mean that this ! 86: * code can cope with arbitrarily-sized write operations (they won't be ! 87: * atomic, but any caller that cares will do the op synchronously). ! 88: */ ! 89: #define MAX_PHYS (256 * 1024) ! 90: ! 91: void minphys(ior) ! 92: register io_req_t ior; ! 93: { ! 94: if ((ior->io_op & (IO_WRITE | IO_READ | IO_OPEN)) == IO_WRITE) ! 95: return; ! 96: ! 97: if (ior->io_count > MAX_PHYS) ! 98: ior->io_count = MAX_PHYS; ! 99: } ! 100: ! 101: /* ! 102: * Dummy routine placed in device switch entries to indicate that ! 103: * block device may be mapped. ! 104: */ ! 105: vm_offset_t block_io_mmap() ! 106: { ! 107: return (0); ! 108: } ! 109: ! 110: /* ! 111: * Disk sort routine. ! 112: * ! 113: * We order the disk request chain so that the disk head will sweep ! 114: * back and forth across the disk. The chain is divided into two ! 115: * pieces, with requests ordered in opposite directions. Assume that ! 116: * the first part of the chain holds increasing cylinder numbers. ! 117: * If a new request has a higher cylinder number than the head of ! 118: * the chain, the disk head has not yet reached it; the new request ! 119: * can go in the first part of the chain. If the new request has ! 120: * a lower cylinder number, the disk head has already passed it and ! 121: * must catch it on the way back; so the new request goes in the ! 122: * second (descending) part of the chain. ! 123: * When all of the requests in the ascending portion are filled, ! 124: * the descending chain becomes the first chain, and requests above ! 125: * the first now go in the second part of the chain (ascending). ! 126: */ ! 127: ! 128: #define io_cylinder io_residual ! 129: /* Disk drivers put cylinder here */ ! 130: #define h_head io_next ! 131: #define h_tail io_prev ! 132: /* IORs are chained here */ ! 133: ! 134: void disksort(head, ior) ! 135: io_req_t head; /* (sort of) */ ! 136: io_req_t ior; ! 137: { ! 138: register int cylinder = ior->io_cylinder; ! 139: register io_req_t next, prev; ! 140: ! 141: next = head->h_head; ! 142: if (next == 0) { ! 143: head->h_head = ior; ! 144: head->h_tail = ior; ! 145: ior->io_next = 0; ! 146: return; ! 147: } ! 148: ! 149: do { ! 150: prev = next; ! 151: next = prev->io_next; ! 152: } while (next != 0 && prev->io_cylinder == next->io_cylinder); ! 153: ! 154: if (next == 0) { ! 155: prev->io_next = ior; ! 156: head->h_tail = ior; ! 157: ior->io_next = 0; ! 158: return; ! 159: } ! 160: ! 161: if (prev->io_cylinder < next->io_cylinder) { ! 162: /* ! 163: * Ascending list first. ! 164: */ ! 165: if (prev->io_cylinder <= cylinder) { ! 166: /* ! 167: * Insert in ascending list. ! 168: */ ! 169: while (next != 0 && ! 170: next->io_cylinder <= cylinder && ! 171: prev->io_cylinder <= next->io_cylinder) ! 172: { ! 173: prev = next; ! 174: next = prev->io_next; ! 175: } ! 176: } ! 177: else { ! 178: /* ! 179: * Insert in descending list ! 180: */ ! 181: do { ! 182: prev = next; ! 183: next = prev->io_next; ! 184: } while (next != 0 && ! 185: prev->io_cylinder <= next->io_cylinder); ! 186: ! 187: while (next != 0 && ! 188: next->io_cylinder >= cylinder) ! 189: { ! 190: prev = next; ! 191: next = prev->io_next; ! 192: } ! 193: } ! 194: } ! 195: else { ! 196: /* ! 197: * Descending first. ! 198: */ ! 199: if (prev->io_cylinder >= cylinder) { ! 200: /* ! 201: * Insert in descending list. ! 202: */ ! 203: while (next != 0 && ! 204: next->io_cylinder >= cylinder && ! 205: prev->io_cylinder >= next->io_cylinder) ! 206: { ! 207: prev = next; ! 208: next = prev->io_next; ! 209: } ! 210: } ! 211: else { ! 212: /* ! 213: * Insert in ascending list ! 214: */ ! 215: do { ! 216: prev = next; ! 217: next = prev->io_next; ! 218: } while (next != 0 && ! 219: prev->io_cylinder >= next->io_cylinder); ! 220: while (next != 0 && ! 221: next->io_cylinder <= cylinder) ! 222: { ! 223: prev = next; ! 224: next = prev->io_next; ! 225: } ! 226: } ! 227: } ! 228: /* ! 229: * Insert between prev and next. ! 230: */ ! 231: prev->io_next = ior; ! 232: ior->io_next = next; ! 233: if (next == 0) { ! 234: /* At tail of list. */ ! 235: head->h_tail = ior; ! 236: } ! 237: } ! 238:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.