Beispiel #1
0
static void delete_device( struct device *device )
{
    struct ioctl_call *ioctl, *next;

    if (!device->manager) return;  /* already deleted */

    /* terminate all pending requests */
    LIST_FOR_EACH_ENTRY_SAFE( ioctl, next, &device->requests, struct ioctl_call, dev_entry )
    {
        list_remove( &ioctl->mgr_entry );
        set_ioctl_result( ioctl, STATUS_FILE_DELETED, NULL, 0 );
    }
    unlink_named_object( &device->obj );
    list_remove( &device->entry );
    device->manager = NULL;
}
Beispiel #2
0
status_t
FileDevice::Control(void* _cookie, int32 op, void* buffer, size_t length)
{
	Cookie* cookie = (Cookie*)_cookie;

	switch (op) {
		case B_GET_DEVICE_SIZE:
			return set_ioctl_result(
				fFileSize > ~(size_t)0 ? ~(size_t)0 : (size_t)fFileSize,
				buffer, length);

		case B_SET_BLOCKING_IO:
		case B_SET_NONBLOCKING_IO:
			// TODO: Translate to O_NONBLOCK and pass on!
			return B_OK;

		case B_GET_READ_STATUS:
		case B_GET_WRITE_STATUS:
			// TODO: poll() the FD!
			return set_ioctl_result(true, buffer, length);

		case B_GET_ICON:
			return B_UNSUPPORTED;

		case B_GET_GEOMETRY:
		case B_GET_BIOS_GEOMETRY:
		{
			// fill in the geometry
			// Optimally we have only 1 block per sector and only one head.
			// Since we have only a uint32 for the cylinder count, this won't
			// work for files > 2TB. So, we set the head count to the minimally
			// possible value.
			off_t blocks = fFileSize / kBlockSize;
			uint32 heads = (blocks + 0xfffffffe) / 0xffffffff;
			if (heads == 0)
				heads = 1;

			device_geometry geometry;
			geometry.bytes_per_sector = kBlockSize;
		    geometry.sectors_per_track = 1;
		    geometry.cylinder_count = blocks / heads;
		    geometry.head_count = heads;
		    geometry.device_type = B_DISK;
		    geometry.removable = false;
		    geometry.read_only = false;
		    geometry.write_once = false;

			return set_ioctl_result(geometry, buffer, length);
		}

		case B_GET_MEDIA_STATUS:
			return set_ioctl_result((status_t)B_OK, buffer, length);

		case B_SET_INTERRUPTABLE_IO:
		case B_SET_UNINTERRUPTABLE_IO:
			return B_OK;

		case B_FLUSH_DRIVE_CACHE:
			return fsync(cookie->fd) == 0 ? B_OK : errno;

		case B_GET_BIOS_DRIVE_ID:
			return set_ioctl_result((uint8)0xf8, buffer, length);

		case B_GET_DRIVER_FOR_DEVICE:
		case B_SET_DEVICE_SIZE:
		case B_SET_PARTITION:
		case B_FORMAT_DEVICE:
		case B_EJECT_DEVICE:
		case B_LOAD_MEDIA:
		case B_GET_NEXT_OPEN_DEVICE:
		default:
			return B_BAD_VALUE;
	}

	return B_OK;
}