Changeset e41369ef in rtems for cpukit/libblock
- Timestamp:
- 10/20/09 07:53:19 (14 years ago)
- Branches:
- 4.10, 4.11, 5, master
- Children:
- d61f0a7b
- Parents:
- b83c7ba9
- Location:
- cpukit/libblock
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/libblock/include/rtems/blkdev.h
rb83c7ba9 re41369ef 163 163 #define RTEMS_BLKIO_GETSIZE _IO('B', 5) 164 164 #define RTEMS_BLKIO_SYNCDEV _IO('B', 6) 165 #define RTEMS_BLKIO_DELETED _IO('B', 7) 165 166 166 167 /** @} */ -
cpukit/libblock/include/rtems/diskdevs.h
rb83c7ba9 re41369ef 4 4 * @ingroup rtems_disk 5 5 * 6 * Block device disk management.6 * @brief Block device disk management API. 7 7 */ 8 8 … … 90 90 * @brief Usage counter. 91 91 * 92 * Devices cannot be removed if they are in use.92 * Devices cannot be deleted if they are in use. 93 93 */ 94 94 unsigned uses; … … 130 130 */ 131 131 void *driver_data; 132 133 /** 134 * @brief Indicates that this disk should be deleted as soon as the last user 135 * releases this disk. 136 */ 137 bool deleted; 132 138 }; 133 139 … … 204 210 * @brief Creates a physical disk with device identifier @a dev. 205 211 * 206 * The block size @a block_size must be a power of two. The disk size @a207 * disk_size is the number of blocks provided by this disk. The block index208 * starts with zero. The associated disk device driver will be invoked via the209 * IO control handler @a handler. A device node will be registered in the file210 * system with absolute path @a name. This function is usually invoked from a212 * The block size @a block_size must be positive. The disk will have 213 * @a block_count blocks. The block index starts with zero. The associated disk 214 * device driver will be invoked via the IO control handler @a handler. A 215 * device node will be registered in the file system with absolute path @a 216 * name, if @a name is not @c NULL. This function is usually invoked from a 211 217 * block device driver during initialization when a physical device is detected 212 218 * in the system. The device driver provides an IO control handler to allow 213 219 * block device operations. 220 * 221 * @retval RTEMS_SUCCESSFUL Successful operation. 222 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex. 223 * @retval RTEMS_INVALID_ADDRESS IO control handler is @c NULL. 224 * @retval RTEMS_INVALID_NUMBER Block size is zero. 225 * @retval RTEMS_NO_MEMORY Not enough memory. 226 * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor is already in use. 227 * @retval RTEMS_UNSATISFIED Cannot create device node. 214 228 */ 215 229 rtems_status_code rtems_disk_create_phys( 216 230 dev_t dev, 217 231 uint32_t block_size, 218 rtems_blkdev_bnum disk_size,232 rtems_blkdev_bnum block_count, 219 233 rtems_block_device_ioctl handler, 220 234 void *driver_data, … … 227 241 * A logical disk manages a subset of consecutive blocks contained in the 228 242 * physical disk with identifier @a phys. The start block index of the logical 229 * disk device is @a start. The block number of the logcal disk will be @a 230 * size. The blocks must be within the range of blocks managed by the 231 * associated physical disk device. A device node will be registered in the 232 * file system with absolute path @a name. The block size and IO control 233 * handler are inherited by the physical disk. 243 * disk device is @a begin_block. The block count of the logcal disk will be 244 * @a block_count. The blocks must be within the range of blocks managed by 245 * the associated physical disk device. A device node will be registered in 246 * the file system with absolute path @a name, if @a name is not @c NULL. The 247 * block size and IO control handler are inherited by the physical disk. 248 * 249 * @retval RTEMS_SUCCESSFUL Successful operation. 250 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex. 251 * @retval RTEMS_INVALID_ID Specified physical disk identifier does not 252 * correspond to a physical disk. 253 * @retval RTEMS_INVALID_NUMBER Begin block or block count are out of range. 254 * @retval RTEMS_NO_MEMORY Not enough memory. 255 * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor for logical disk 256 * identifier is already in use. 257 * @retval RTEMS_UNSATISFIED Cannot create device node. 234 258 */ 235 259 rtems_status_code rtems_disk_create_log( 236 260 dev_t dev, 237 261 dev_t phys, 238 rtems_blkdev_bnum start,239 rtems_blkdev_bnum size,262 rtems_blkdev_bnum begin_block, 263 rtems_blkdev_bnum block_count, 240 264 const char *name 241 265 ); … … 244 268 * @brief Deletes a physical or logical disk device with identifier @a dev. 245 269 * 246 * Disk devices may be deleted if there usage counter (and the usage counters 247 * of all contained logical disks devices) equals zero. When a physical disk 248 * device is deleted, all logical disk devices will deleted too. The 249 * corresponding device nodes will be removed from the file system. 270 * Marks the disk device as deleted. When a physical disk device is deleted, 271 * all corresponding logical disk devices will marked as deleted too. Disks 272 * that are marked as deleted and have a usage counter of zero will be deleted. 273 * The corresponding device nodes will be removed from the file system. In 274 * case of a physical disk deletion the IO control handler will be invoked with 275 * a RTEMS_BLKIO_DELETED request. Disks that are still in use will be deleted 276 * upon release. 277 * 278 * @retval RTEMS_SUCCESSFUL Successful operation. 279 * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex. 280 * @retval RTEMS_INVALID_ID No disk for specified device identifier. 250 281 */ 251 282 rtems_status_code rtems_disk_delete(dev_t dev); … … 255 286 * 256 287 * Increments usage counter by one. You should release the disk device 257 * descriptor with rtems_disk_release(). Returns @c NULL if no corresponding 288 * descriptor with rtems_disk_release(). 289 * 290 * @return Pointer to the disk device descriptor or @c NULL if no corresponding 258 291 * disk exists. 259 292 */ … … 261 294 262 295 /** 263 * @brief Releases the disk device descript ion@a dd.296 * @brief Releases the disk device descriptor @a dd. 264 297 * 265 298 * Decrements usage counter by one. 299 * 300 * @retval RTEMS_SUCCESSFUL Successful operation. 266 301 */ 267 302 rtems_status_code rtems_disk_release(rtems_disk_device *dd); … … 274 309 * @{ 275 310 */ 311 312 /** 313 * @brief Initializes the disk device management. 314 * 315 * This functions returns successful if the disk device management is already 316 * initialized. There is no protection against concurrent access. 317 * 318 * @retval RTEMS_SUCCESSFUL Successful initialization. 319 * @retval RTEMS_NO_MEMORY Not enough memory or no semaphore available. 320 * @retval RTEMS_UNSATISFIED Block device buffer initialization failed. 321 */ 322 rtems_status_code rtems_disk_io_initialize(void); 323 324 /** 325 * @brief Releases all resources allocated for disk device management. 326 * 327 * There is no protection against concurrent access. If parts of the system 328 * are still in use the behaviour is undefined. 329 * 330 * @retval RTEMS_SUCCESSFUL Successful operation. 331 */ 332 rtems_status_code rtems_disk_io_done(void); 333 334 /** @} */ 335 336 /** @} */ 276 337 277 338 /** … … 292 353 rtems_disk_device *rtems_disk_next(dev_t dev); 293 354 294 /**295 * @brief Initializes the disk device management.296 *297 * This functions returns successful if the disk device management is already298 * initialized. There is no protection against concurrent access.299 */300 rtems_status_code rtems_disk_io_initialize(void);301 302 /**303 * @brief Releases all resources allocated for disk device management.304 */305 rtems_status_code rtems_disk_io_done(void);306 307 /** @} */308 309 /** @} */310 311 355 #ifdef __cplusplus 312 356 } -
cpukit/libblock/include/rtems/ramdisk.h
rb83c7ba9 re41369ef 75 75 */ 76 76 extern size_t rtems_ramdisk_configuration_size; 77 78 int ramdisk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp);79 77 80 78 /** … … 143 141 extern const rtems_driver_address_table ramdisk_ops; 144 142 143 int ramdisk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp); 144 145 145 /** 146 146 * @brief Allocates and initializes a RAM disk descriptor. … … 154 154 * if no memory is available. 155 155 * 156 * @note 157 * Runtime configuration example: 156 158 * @code 159 * #include <rtems.h> 160 * #include <rtems/libio.h> 161 * #include <rtems/ramdisk.h> 162 * 157 163 * rtems_status_code create_ramdisk( 158 164 * const char *disk_name_path, -
cpukit/libblock/src/diskdevs.c
rb83c7ba9 re41369ef 4 4 * @ingroup rtems_disk 5 5 * 6 * Block device disk management.6 * @brief Block device disk management implementation. 7 7 */ 8 8 … … 11 11 * Author: Victor V. Vengerov <vvv@oktet.ru> 12 12 * 13 * Copyright (c) 2009 embedded brains GmbH. 14 * 13 15 * @(#) $Id$ 14 16 */ … … 18 20 #endif 19 21 22 #include <stdlib.h> 23 #include <unistd.h> 24 #include <string.h> 25 20 26 #include <rtems.h> 21 27 #include <rtems/libio.h> 22 #include <stdlib.h> 23 #include <unistd.h> /* unlink */ 24 #include <string.h> 25 26 #include "rtems/diskdevs.h" 27 #include "rtems/bdbuf.h" 28 29 #define DISKTAB_INITIAL_SIZE 32 28 #include <rtems/diskdevs.h> 29 #include <rtems/blkdev.h> 30 #include <rtems/bdbuf.h> 31 32 #define DISKTAB_INITIAL_SIZE 8 30 33 31 34 /* Table of disk devices having the same major number */ 32 35 typedef struct rtems_disk_device_table { 33 34 uint32_t size;/* Number of entries in the table */36 rtems_disk_device **minor; /* minor-indexed disk device table */ 37 rtems_device_minor_number size; /* Number of entries in the table */ 35 38 } rtems_disk_device_table; 36 39 … … 39 42 40 43 /* Number of allocated entries in disktab table */ 41 static uint32_tdisktab_size;44 static rtems_device_major_number disktab_size; 42 45 43 46 /* Mutual exclusion semaphore for disk devices table */ 44 47 static rtems_id diskdevs_mutex; 45 46 /* Flag meaning that disk I/O, buffering etc. already has been initialized. */47 static bool disk_io_initialized = false;48 48 49 49 /* diskdevs data structures protection flag. … … 60 60 static volatile bool diskdevs_protected; 61 61 62 /* create_disk_entry -- 63 * Return pointer to the disk_entry structure for the specified device, or 64 * create one if it is not exists. 65 * 66 * PARAMETERS: 67 * dev - device id (major, minor) 68 * 69 * RETURNS: 70 * pointer to the disk device descriptor entry, or NULL if no memory 71 * available for its creation. 72 */ 73 static rtems_disk_device * 74 create_disk_entry(dev_t dev) 75 { 76 rtems_device_major_number major; 77 rtems_device_minor_number minor; 78 rtems_disk_device **d; 79 80 rtems_filesystem_split_dev_t (dev, major, minor); 81 82 if (major >= disktab_size) 83 { 84 rtems_disk_device_table *p; 85 uint32_t newsize; 86 uint32_t i; 87 newsize = disktab_size * 2; 88 if (major >= newsize) 89 newsize = major + 1; 90 p = realloc(disktab, sizeof(rtems_disk_device_table) * newsize); 91 if (p == NULL) 92 return NULL; 93 disktab = p; 94 p += disktab_size; 95 for (i = disktab_size; i < newsize; i++, p++) 96 { 97 p->minor = NULL; 98 p->size = 0; 99 } 100 disktab_size = newsize; 101 } 102 103 if ((disktab[major].minor == NULL) || 104 (minor >= disktab[major].size)) 105 { 106 uint32_t newsize; 107 rtems_disk_device **p; 108 uint32_t i; 109 uint32_t s = disktab[major].size; 110 111 if (s == 0) 112 newsize = DISKTAB_INITIAL_SIZE; 113 else 114 newsize = s * 2; 115 if (minor >= newsize) 116 newsize = minor + 1; 117 118 p = realloc(disktab[major].minor, 119 sizeof(rtems_disk_device *) * newsize); 120 if (p == NULL) 121 return NULL; 122 disktab[major].minor = p; 123 p += s; 124 for (i = s; i < newsize; i++, p++) 125 *p = NULL; 126 disktab[major].size = newsize; 127 } 128 129 d = disktab[major].minor + minor; 130 if (*d == NULL) 131 { 132 *d = calloc(1, sizeof(rtems_disk_device)); 133 } 134 return *d; 135 } 136 137 /* get_disk_entry -- 138 * Get disk device descriptor by device number. 139 * 140 * PARAMETERS: 141 * dev - block device number 142 * 143 * RETURNS: 144 * Pointer to the disk device descriptor corresponding to the specified 145 * device number, or NULL if disk device with such number not exists. 146 */ 62 static rtems_status_code 63 disk_lock(void) 64 { 65 rtems_status_code sc = RTEMS_SUCCESSFUL; 66 67 sc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 68 if (sc == RTEMS_SUCCESSFUL) { 69 diskdevs_protected = true; 70 71 return RTEMS_SUCCESSFUL; 72 } else { 73 return RTEMS_NOT_CONFIGURED; 74 } 75 } 76 77 static void 78 disk_unlock(void) 79 { 80 rtems_status_code sc = RTEMS_SUCCESSFUL; 81 82 diskdevs_protected = false; 83 84 sc = rtems_semaphore_release(diskdevs_mutex); 85 if (sc != RTEMS_SUCCESSFUL) { 86 /* FIXME: Error number */ 87 rtems_fatal_error_occurred(0xdeadbeef); 88 } 89 } 90 147 91 static rtems_disk_device * 148 92 get_disk_entry(dev_t dev) 149 93 { 150 rtems_device_major_number major; 151 rtems_device_minor_number minor; 152 rtems_disk_device_table *dtab; 153 154 rtems_filesystem_split_dev_t (dev, major, minor); 155 156 if ((major >= disktab_size) || (disktab == NULL)) 157 return NULL; 158 159 dtab = disktab + major; 160 161 if ((minor >= dtab->size) || (dtab->minor == NULL)) 162 return NULL; 163 164 return dtab->minor[minor]; 165 } 166 167 /* create_disk -- 168 * Check that disk entry for specified device number is not defined 169 * and create it. 170 * 171 * PARAMETERS: 172 * dev - device identifier (major, minor numbers) 173 * name - character name of device (e.g. /dev/hda) 174 * disdev - placeholder for pointer to created disk descriptor 175 * 176 * RETURNS: 177 * RTEMS_SUCCESSFUL if disk entry successfully created, or 178 * error code if error occured (device already registered, 179 * no memory available). 180 */ 94 rtems_device_major_number major = 0; 95 rtems_device_minor_number minor = 0; 96 97 rtems_filesystem_split_dev_t(dev, major, minor); 98 99 if (major < disktab_size && disktab != NULL) { 100 rtems_disk_device_table *dtab = disktab + major; 101 102 if (minor < dtab->size && dtab->minor != NULL) { 103 rtems_disk_device *dd = dtab->minor [minor]; 104 105 if (dd != NULL && !dd->deleted) { 106 ++dd->uses; 107 108 return dd; 109 } 110 } 111 } 112 113 return NULL; 114 } 115 116 static rtems_disk_device ** 117 create_disk_table_entry(dev_t dev) 118 { 119 rtems_device_major_number major = 0; 120 rtems_device_minor_number minor = 0; 121 122 rtems_filesystem_split_dev_t(dev, major, minor); 123 124 if (major >= disktab_size) { 125 rtems_disk_device_table *table = disktab; 126 rtems_device_major_number old_size = disktab_size; 127 rtems_device_major_number new_size = 2 * old_size; 128 129 if (major >= new_size) { 130 new_size = major + 1; 131 } 132 133 table = realloc(table, new_size * sizeof(*table)); 134 if (table == NULL) { 135 return NULL; 136 } 137 138 memset(table + old_size, 0, (new_size - old_size) * sizeof(*table)); 139 disktab = table; 140 disktab_size = new_size; 141 } 142 143 if (disktab [major].minor == NULL || minor >= disktab[major].size) { 144 rtems_disk_device **table = disktab [major].minor; 145 rtems_device_minor_number old_size = disktab [major].size; 146 rtems_device_minor_number new_size = 0; 147 148 if (old_size == 0) { 149 new_size = DISKTAB_INITIAL_SIZE; 150 } else { 151 new_size = 2 * old_size; 152 } 153 if (minor >= new_size) { 154 new_size = minor + 1; 155 } 156 157 table = realloc(table, new_size * sizeof(*table)); 158 if (table == NULL) { 159 return NULL; 160 } 161 162 memset(table + old_size, 0, (new_size - old_size) * sizeof(*table)); 163 disktab [major].minor = table; 164 disktab [major].size = new_size; 165 } 166 167 return disktab [major].minor + minor; 168 } 169 181 170 static rtems_status_code 182 create_disk(dev_t dev, const char *name, rtems_disk_device **diskdev) 183 { 184 rtems_disk_device *dd; 185 char *n; 186 187 dd = get_disk_entry(dev); 188 if (dd != NULL) 189 { 190 return RTEMS_RESOURCE_IN_USE; 191 } 192 193 if (name == NULL) 194 { 195 n = NULL; 196 } 197 else 198 { 199 int nlen = strlen(name) + 1; 200 n = malloc(nlen); 201 if (n == NULL) 202 return RTEMS_NO_MEMORY; 203 strncpy(n, name, nlen); 204 } 205 206 dd = create_disk_entry(dev); 207 if (dd == NULL) 208 { 209 free(n); 210 return RTEMS_NO_MEMORY; 211 } 212 213 dd->dev = dev; 214 dd->name = n; 215 216 *diskdev = dd; 217 218 return RTEMS_SUCCESSFUL; 171 create_disk(dev_t dev, const char *name, rtems_disk_device **dd_ptr) 172 { 173 rtems_status_code sc = RTEMS_SUCCESSFUL; 174 rtems_disk_device **dd_entry = create_disk_table_entry(dev); 175 rtems_disk_device *dd = NULL; 176 char *alloc_name = NULL; 177 178 if (dd_entry == NULL) { 179 return RTEMS_NO_MEMORY; 180 } 181 182 if (*dd_entry != NULL) { 183 return RTEMS_RESOURCE_IN_USE; 184 } 185 186 dd = malloc(sizeof(*dd)); 187 if (dd == NULL) { 188 return RTEMS_NO_MEMORY; 189 } 190 191 if (name != NULL) { 192 alloc_name = strdup(name); 193 194 if (alloc_name == NULL) { 195 free(dd); 196 197 return RTEMS_NO_MEMORY; 198 } 199 } 200 201 if (name != NULL) { 202 rtems_device_major_number major = 0; 203 rtems_device_minor_number minor = 0; 204 205 rtems_filesystem_split_dev_t(dev, major, minor); 206 207 sc = rtems_io_register_name(name, major, minor); 208 if (sc != RTEMS_SUCCESSFUL) { 209 free(alloc_name); 210 free(dd); 211 212 return RTEMS_UNSATISFIED; 213 } 214 } 215 216 dd->dev = dev; 217 dd->name = alloc_name; 218 dd->uses = 0; 219 dd->deleted = false; 220 221 *dd_entry = dd; 222 *dd_ptr = dd; 223 224 return RTEMS_SUCCESSFUL; 219 225 } 220 226 … … 222 228 dev_t dev, 223 229 uint32_t block_size, 224 rtems_blkdev_bnum disk_size,230 rtems_blkdev_bnum block_count, 225 231 rtems_block_device_ioctl handler, 226 232 void *driver_data, … … 228 234 ) 229 235 { 230 rtems_disk_device *dd; 231 rtems_status_code rc; 232 rtems_device_major_number major; 233 rtems_device_minor_number minor; 234 235 rtems_filesystem_split_dev_t (dev, major, minor); 236 237 rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 238 if (rc != RTEMS_SUCCESSFUL) 239 return rc; 240 diskdevs_protected = true; 241 242 rc = create_disk(dev, name, &dd); 243 if (rc != RTEMS_SUCCESSFUL) 244 { 245 diskdevs_protected = false; 246 rtems_semaphore_release(diskdevs_mutex); 247 return rc; 248 } 249 250 dd->phys_dev = dd; 251 dd->uses = 0; 252 dd->start = 0; 253 dd->size = disk_size; 254 dd->block_size = dd->media_block_size = block_size; 255 dd->ioctl = handler; 256 dd->driver_data = driver_data; 257 258 rc = rtems_io_register_name(name, major, minor); 259 260 if (handler (dd, RTEMS_BLKDEV_CAPABILITIES, &dd->capabilities) < 0) 261 dd->capabilities = 0; 262 263 diskdevs_protected = false; 264 rtems_semaphore_release(diskdevs_mutex); 265 266 return rc; 236 rtems_disk_device *dd = NULL; 237 rtems_status_code sc = RTEMS_SUCCESSFUL; 238 239 if (handler == NULL) { 240 return RTEMS_INVALID_ADDRESS; 241 } 242 243 if (block_size == 0) { 244 return RTEMS_INVALID_NUMBER; 245 } 246 247 sc = disk_lock(); 248 if (sc != RTEMS_SUCCESSFUL) { 249 return sc; 250 } 251 252 sc = create_disk(dev, name, &dd); 253 if (sc != RTEMS_SUCCESSFUL) { 254 disk_unlock(); 255 256 return sc; 257 } 258 259 dd->phys_dev = dd; 260 dd->start = 0; 261 dd->size = block_count; 262 dd->block_size = dd->media_block_size = block_size; 263 dd->ioctl = handler; 264 dd->driver_data = driver_data; 265 266 if ((*handler)(dd, RTEMS_BLKDEV_CAPABILITIES, &dd->capabilities) < 0) { 267 dd->capabilities = 0; 268 } 269 270 disk_unlock(); 271 272 return RTEMS_SUCCESSFUL; 273 } 274 275 static bool 276 is_physical_disk(const rtems_disk_device *dd) 277 { 278 return dd->phys_dev == dd; 267 279 } 268 280 … … 270 282 dev_t dev, 271 283 dev_t phys, 272 rtems_blkdev_bnum start,273 rtems_blkdev_bnum size,284 rtems_blkdev_bnum begin_block, 285 rtems_blkdev_bnum block_count, 274 286 const char *name 275 287 ) 276 288 { 289 rtems_status_code sc = RTEMS_SUCCESSFUL; 290 rtems_disk_device *physical_disk = NULL; 277 291 rtems_disk_device *dd = NULL; 278 rtems_disk_device *pdd = NULL; 279 rtems_status_code rc = RTEMS_SUCCESSFUL; 292 rtems_blkdev_bnum end_block = begin_block + block_count; 293 294 sc = disk_lock(); 295 if (sc != RTEMS_SUCCESSFUL) { 296 return sc; 297 } 298 299 physical_disk = get_disk_entry(phys); 300 if (physical_disk == NULL || !is_physical_disk(physical_disk)) { 301 if (physical_disk != NULL) { 302 --physical_disk->uses; 303 } 304 disk_unlock(); 305 306 return RTEMS_INVALID_ID; 307 } 308 309 if ( 310 begin_block >= physical_disk->size 311 || end_block <= begin_block 312 || end_block > physical_disk->size 313 ) { 314 --physical_disk->uses; 315 disk_unlock(); 316 317 return RTEMS_INVALID_NUMBER; 318 } 319 320 sc = create_disk(dev, name, &dd); 321 if (sc != RTEMS_SUCCESSFUL) { 322 --physical_disk->uses; 323 disk_unlock(); 324 325 return sc; 326 } 327 328 dd->phys_dev = physical_disk; 329 dd->start = begin_block; 330 dd->size = block_count; 331 dd->block_size = dd->media_block_size = physical_disk->block_size; 332 dd->ioctl = physical_disk->ioctl; 333 dd->driver_data = physical_disk->driver_data; 334 335 disk_unlock(); 336 337 return RTEMS_SUCCESSFUL; 338 } 339 340 static void 341 free_disk_device(rtems_disk_device *dd) 342 { 343 if (is_physical_disk(dd)) { 344 (*dd->ioctl)(dd, RTEMS_BLKIO_DELETED, NULL); 345 } 346 if (dd->name != NULL) { 347 unlink(dd->name); 348 free(dd->name); 349 } 350 free(dd); 351 } 352 353 static void 354 rtems_disk_cleanup(rtems_disk_device *disk_to_remove) 355 { 356 rtems_disk_device *const physical_disk = disk_to_remove->phys_dev; 280 357 rtems_device_major_number major = 0; 281 358 rtems_device_minor_number minor = 0; 282 rtems_blkdev_bnum end = start + size; 283 284 rtems_filesystem_split_dev_t (dev, major, minor); 285 286 rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 287 if (rc != RTEMS_SUCCESSFUL) { 288 return rc; 289 } 290 291 diskdevs_protected = true; 292 293 pdd = get_disk_entry(phys); 294 if ( 295 pdd == NULL 296 || pdd != pdd->phys_dev 297 || start >= pdd->size 298 || end <= start 299 || end > pdd->size 300 ) { 301 diskdevs_protected = false; 302 rtems_semaphore_release(diskdevs_mutex); 303 return RTEMS_INVALID_NUMBER; 304 } 305 306 rc = create_disk(dev, name, &dd); 307 if (rc != RTEMS_SUCCESSFUL) { 308 diskdevs_protected = false; 309 rtems_semaphore_release(diskdevs_mutex); 310 return rc; 311 } 312 313 dd->phys_dev = pdd; 314 dd->uses = 0; 315 dd->start = start; 316 dd->size = size; 317 dd->block_size = dd->media_block_size = pdd->block_size; 318 dd->ioctl = pdd->ioctl; 319 dd->driver_data = pdd->driver_data; 320 321 rc = rtems_io_register_name(name, major, minor); 322 323 diskdevs_protected = false; 324 rc = rtems_semaphore_release(diskdevs_mutex); 325 326 return rc; 327 } 328 329 rtems_status_code 330 rtems_disk_delete(dev_t dev) 331 { 332 rtems_status_code rc = RTEMS_SUCCESSFUL; 333 rtems_device_major_number maj = 0; 334 rtems_device_minor_number min = 0; 335 rtems_disk_device *dd = NULL; 336 bool physical_disk = true; 337 338 rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 339 if (rc != RTEMS_SUCCESSFUL) { 340 return rc; 341 } 342 diskdevs_protected = true; 343 344 /* Check if we have a physical or logical disk */ 345 dd = get_disk_entry(dev); 346 if (dd == NULL) { 347 return RTEMS_INVALID_NUMBER; 348 } 349 physical_disk = dd->phys_dev == dd; 350 351 if (physical_disk) { 352 unsigned used = 0; 353 354 /* Check if this device is in use -- calculate usage counter */ 355 for (maj = 0; maj < disktab_size; maj++) { 356 rtems_disk_device_table *dtab = disktab + maj; 357 if (dtab != NULL) { 358 for (min = 0; min < dtab->size; min++) { 359 dd = dtab->minor[min]; 360 if ((dd != NULL) && (dd->phys_dev->dev == dev)) { 361 used += dd->uses; 359 360 if (physical_disk->deleted) { 361 dev_t dev = physical_disk->dev; 362 unsigned deleted_count = 0; 363 364 for (major = 0; major < disktab_size; ++major) { 365 rtems_disk_device_table *dtab = disktab + major; 366 367 for (minor = 0; minor < dtab->size; ++minor) { 368 rtems_disk_device *dd = dtab->minor [minor]; 369 370 if (dd != NULL && dd->phys_dev->dev == dev && dd != physical_disk) { 371 if (dd->uses == 0) { 372 ++deleted_count; 373 dtab->minor [minor] = NULL; 374 free_disk_device(dd); 375 } else { 376 dd->deleted = true; 362 377 } 363 378 } … … 365 380 } 366 381 367 if (used != 0) { 368 diskdevs_protected = false; 369 rtems_semaphore_release(diskdevs_mutex); 370 return RTEMS_RESOURCE_IN_USE; 371 } 372 373 /* Delete this device and all of its logical devices */ 374 for (maj = 0; maj < disktab_size; maj++) { 375 rtems_disk_device_table *dtab = disktab + maj; 376 if (dtab != NULL) { 377 for (min = 0; min < dtab->size; min++) { 378 dd = dtab->minor[min]; 379 if ((dd != NULL) && (dd->phys_dev->dev == dev)) { 380 unlink(dd->name); 381 free(dd->name); 382 free(dd); 383 dtab->minor[min] = NULL; 384 } 385 } 386 } 382 physical_disk->uses -= deleted_count; 383 if (physical_disk->uses == 0) { 384 rtems_filesystem_split_dev_t(physical_disk->dev, major, minor); 385 disktab [major].minor [minor] = NULL; 386 free_disk_device(physical_disk); 387 387 } 388 388 } else { 389 rtems_filesystem_split_dev_t(dev, maj, min); 390 disktab[maj].minor[min] = NULL; 391 unlink(dd->name); 392 free(dd->name); 393 free(dd); 394 } 395 396 diskdevs_protected = false; 397 rc = rtems_semaphore_release(diskdevs_mutex); 398 return rc; 389 if (disk_to_remove->uses == 0) { 390 --physical_disk->uses; 391 rtems_filesystem_split_dev_t(disk_to_remove->dev, major, minor); 392 disktab [major].minor [minor] = NULL; 393 free_disk_device(disk_to_remove); 394 } 395 } 396 } 397 398 rtems_status_code 399 rtems_disk_delete(dev_t dev) 400 { 401 rtems_status_code sc = RTEMS_SUCCESSFUL; 402 rtems_disk_device *dd = NULL; 403 404 sc = disk_lock(); 405 if (sc != RTEMS_SUCCESSFUL) { 406 return sc; 407 } 408 409 dd = get_disk_entry(dev); 410 if (dd == NULL) { 411 disk_unlock(); 412 413 return RTEMS_INVALID_ID; 414 } 415 416 --dd->uses; 417 dd->deleted = true; 418 rtems_disk_cleanup(dd); 419 420 disk_unlock(); 421 422 return RTEMS_SUCCESSFUL; 399 423 } 400 424 … … 402 426 rtems_disk_obtain(dev_t dev) 403 427 { 404 rtems_interrupt_level level; 405 rtems_disk_device *dd; 406 rtems_status_code rc; 407 408 rtems_interrupt_disable(level); 409 if (diskdevs_protected) 410 { 411 rtems_interrupt_enable(level); 412 rc = rtems_semaphore_obtain(diskdevs_mutex, RTEMS_WAIT, 413 RTEMS_NO_TIMEOUT); 414 if (rc != RTEMS_SUCCESSFUL) 415 return NULL; 416 diskdevs_protected = true; 417 dd = get_disk_entry(dev); 418 dd->uses++; 419 diskdevs_protected = false; 420 rtems_semaphore_release(diskdevs_mutex); 421 return dd; 422 } 423 else 424 { 425 /* Frequent and quickest case */ 426 dd = get_disk_entry(dev); 427 dd->uses++; 428 rtems_interrupt_enable(level); 429 return dd; 430 } 428 rtems_status_code sc = RTEMS_SUCCESSFUL; 429 rtems_disk_device *dd = NULL; 430 rtems_interrupt_level level; 431 432 rtems_interrupt_disable(level); 433 if (!diskdevs_protected) { 434 /* Frequent and quickest case */ 435 dd = get_disk_entry(dev); 436 rtems_interrupt_enable(level); 437 } else { 438 rtems_interrupt_enable(level); 439 440 sc = disk_lock(); 441 if (sc == RTEMS_SUCCESSFUL) { 442 dd = get_disk_entry(dev); 443 disk_unlock(); 444 } 445 } 446 447 return dd; 431 448 } 432 449 … … 434 451 rtems_disk_release(rtems_disk_device *dd) 435 452 { 436 rtems_interrupt_level level; 437 rtems_interrupt_disable(level); 438 dd->uses--; 439 rtems_interrupt_enable(level); 440 return RTEMS_SUCCESSFUL; 453 rtems_interrupt_level level; 454 dev_t dev = dd->dev; 455 unsigned uses = 0; 456 bool deleted = false; 457 458 rtems_interrupt_disable(level); 459 uses = --dd->uses; 460 deleted = dd->deleted; 461 rtems_interrupt_enable(level); 462 463 if (uses == 0 && deleted) { 464 rtems_disk_delete(dev); 465 } 466 467 return RTEMS_SUCCESSFUL; 441 468 } 442 469 … … 476 503 rtems_disk_io_initialize(void) 477 504 { 478 rtems_status_code rc; 479 480 if (disk_io_initialized) 481 return RTEMS_SUCCESSFUL; 482 483 disktab_size = DISKTAB_INITIAL_SIZE; 484 disktab = calloc(disktab_size, sizeof(rtems_disk_device_table)); 485 if (disktab == NULL) 486 return RTEMS_NO_MEMORY; 487 488 diskdevs_protected = false; 489 rc = rtems_semaphore_create( 490 rtems_build_name('D', 'D', 'E', 'V'), 1, 491 RTEMS_FIFO | RTEMS_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | 492 RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0, &diskdevs_mutex); 493 494 if (rc != RTEMS_SUCCESSFUL) 495 { 496 free(disktab); 497 return rc; 498 } 499 500 rc = rtems_bdbuf_init(); 501 502 if (rc != RTEMS_SUCCESSFUL) 503 { 504 rtems_semaphore_delete(diskdevs_mutex); 505 free(disktab); 506 return rc; 507 } 508 509 disk_io_initialized = 1; 505 rtems_status_code sc = RTEMS_SUCCESSFUL; 506 rtems_device_major_number size = DISKTAB_INITIAL_SIZE; 507 508 if (disktab_size > 0) { 510 509 return RTEMS_SUCCESSFUL; 510 } 511 512 disktab = calloc(size, sizeof(rtems_disk_device_table)); 513 if (disktab == NULL) { 514 return RTEMS_NO_MEMORY; 515 } 516 517 diskdevs_protected = false; 518 sc = rtems_semaphore_create( 519 rtems_build_name('D', 'D', 'E', 'V'), 520 1, 521 RTEMS_FIFO | RTEMS_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY 522 | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 523 0, 524 &diskdevs_mutex 525 ); 526 if (sc != RTEMS_SUCCESSFUL) { 527 free(disktab); 528 529 return RTEMS_NO_MEMORY; 530 } 531 532 sc = rtems_bdbuf_init(); 533 if (sc != RTEMS_SUCCESSFUL) { 534 rtems_semaphore_delete(diskdevs_mutex); 535 free(disktab); 536 537 return RTEMS_UNSATISFIED; 538 } 539 540 disktab_size = size; 541 542 return RTEMS_SUCCESSFUL; 511 543 } 512 544 … … 514 546 rtems_disk_io_done(void) 515 547 { 516 rtems_device_major_number maj; 517 rtems_device_minor_number min; 518 rtems_status_code rc; 519 520 /* Free data structures */ 521 for (maj = 0; maj < disktab_size; maj++) 522 { 523 rtems_disk_device_table *dtab = disktab + maj; 524 if (dtab != NULL) 525 { 526 for (min = 0; min < dtab->size; min++) 527 { 528 rtems_disk_device *dd = dtab->minor[min]; 529 unlink(dd->name); 530 free(dd->name); 531 free(dd); 532 } 533 free(dtab); 534 } 535 } 536 free(disktab); 537 538 rc = rtems_semaphore_delete(diskdevs_mutex); 539 540 disk_io_initialized = 0; 541 return rc; 542 } 548 rtems_device_major_number major = 0; 549 rtems_device_minor_number minor = 0; 550 551 for (major = 0; major < disktab_size; ++major) { 552 rtems_disk_device_table *dtab = disktab + major; 553 554 for (minor = 0; minor < dtab->size; ++minor) { 555 rtems_disk_device *dd = dtab->minor [minor]; 556 557 if (dd != NULL) { 558 free_disk_device(dd); 559 } 560 } 561 free(dtab->minor); 562 } 563 free(disktab); 564 565 rtems_semaphore_delete(diskdevs_mutex); 566 567 diskdevs_mutex = RTEMS_ID_NONE; 568 disktab = NULL; 569 disktab_size = 0; 570 571 return RTEMS_SUCCESSFUL; 572 } -
cpukit/libblock/src/ramdisk-driver.c
rb83c7ba9 re41369ef 14 14 */ 15 15 16 #include <stdio.h> 16 /* FIXME: How to set this define? */ 17 #if !defined(RTEMS_RAMDISK_TRACE) 18 #define RTEMS_RAMDISK_TRACE 0 19 #endif 20 17 21 #include <stdlib.h> 18 22 #include <errno.h> 19 23 #include <string.h> 20 #include <inttypes.h> 24 25 #if RTEMS_RAMDISK_TRACE 26 #include <stdio.h> 27 #endif 21 28 22 29 #include <rtems.h> 23 30 #include <rtems/ramdisk.h> 24 31 25 static void 26 rtems_ramdisk_printf (const ramdisk *rd, const char *format, ...) 27 { 28 if (rd->trace) 29 { 30 va_list args; 31 va_start (args, format); 32 printf ("ramdisk:"); 33 vprintf (format, args); 34 printf ("\n"); 35 } 36 } 32 #if RTEMS_RAMDISK_TRACE 33 static void 34 rtems_ramdisk_printf (const ramdisk *rd, const char *format, ...) 35 { 36 if (rd->trace) 37 { 38 va_list args; 39 va_start (args, format); 40 printf ("ramdisk:"); 41 vprintf (format, args); 42 printf ("\n"); 43 } 44 } 45 #endif 37 46 38 47 static int … … 43 52 rtems_blkdev_sg_buffer *sg; 44 53 54 #if RTEMS_RAMDISK_TRACE 45 55 rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d", 46 56 req->bufs[0].block, req->bufnum); 57 #endif 47 58 48 59 for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) 49 60 { 61 #if RTEMS_RAMDISK_TRACE 50 62 rtems_ramdisk_printf (rd, "ramdisk read: buf=%d block=%d length=%d off=%d addr=%p", 51 63 i, sg->block, sg->length, sg->block * rd->block_size, 52 64 from + (sg->block * rd->block_size)); 65 #endif 53 66 memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length); 54 67 } … … 64 77 rtems_blkdev_sg_buffer *sg; 65 78 79 #if RTEMS_RAMDISK_TRACE 66 80 rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d", 67 81 req->bufs[0].block, req->bufnum); 82 #endif 68 83 for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) 69 84 { 85 #if RTEMS_RAMDISK_TRACE 70 86 rtems_ramdisk_printf (rd, "ramdisk write: buf=%d block=%d length=%d off=%d addr=%p", 71 87 i, sg->block, sg->length, sg->block * rd->block_size, 72 88 to + (sg->block * rd->block_size)); 89 #endif 73 90 memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length); 74 91 }
Note: See TracChangeset
for help on using the changeset viewer.