diff --git a/headers/private/kernel/fs/devfs.h b/headers/private/kernel/fs/devfs.h index 6968da2164..44db6e7efb 100644 --- a/headers/private/kernel/fs/devfs.h +++ b/headers/private/kernel/fs/devfs.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2002-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -29,6 +29,9 @@ status_t devfs_publish_device(const char *path, device_hooks *calls); status_t devfs_publish_directory(const char *path); status_t devfs_rescan_driver(const char *driverName); +void devfs_compute_geometry_size(device_geometry* geometry, uint64 blockCount, + uint32 blockSize); + #ifdef __cplusplus } #endif diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp index e01fd5ef6e..f2a65fb66e 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_cd/scsi_cd.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2010, Haiku, Inc. All rights reserved. + * Copyright 2004-2012, Haiku, Inc. All rights reserved. * Copyright 2002-2003, Thomas Kurschel. All rights reserved. * * Distributed under the terms of the MIT License. @@ -21,6 +21,7 @@ #include +#include #include #include @@ -205,10 +206,8 @@ get_geometry(cd_handle *handle, device_geometry *geometry) if (status == B_DEV_MEDIA_CHANGED) return B_DEV_MEDIA_CHANGED; - geometry->bytes_per_sector = info->block_size; - geometry->sectors_per_track = 1; - geometry->cylinder_count = info->capacity; - geometry->head_count = 1; + devfs_compute_geometry_size(geometry, info->capacity, info->block_size); + geometry->device_type = info->device_type; geometry->removable = info->removable; diff --git a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp index 0f2fe7f220..655ffc3728 100644 --- a/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/scsi/scsi_disk/scsi_disk.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2008-2012, Axel Dörfler, axeld@pinc-software.de. * Copyright 2002/03, Thomas Kurschel. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -20,6 +20,8 @@ #include #include +#include + #include "dma_resources.h" #include "IORequest.h" #include "IOSchedulerSimple.h" @@ -65,7 +67,7 @@ static device_manager_info* sDeviceManager; static status_t -update_capacity(das_driver_info *device) +update_capacity(das_driver_info* device) { TRACE("update_capacity()\n"); @@ -88,20 +90,12 @@ get_geometry(das_handle* handle, device_geometry* geometry) das_driver_info* info = handle->info; status_t status = update_capacity(info); - if (status < B_OK) + if (status != B_OK) return status; - geometry->bytes_per_sector = info->block_size; - if (info->capacity > UINT_MAX) { - // TODO this doesn't work for capacity greater than 35TB - geometry->sectors_per_track = 256; - geometry->cylinder_count = info->capacity / (256 * 32); - geometry->head_count = 32; - } else { - geometry->sectors_per_track = 1; - geometry->cylinder_count = info->capacity; - geometry->head_count = 1; - } + + devfs_compute_geometry_size(geometry, info->capacity, info->block_size); + geometry->device_type = B_DISK; geometry->removable = info->removable; diff --git a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp index 70236c5c6f..c5c82b1bce 100644 --- a/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp +++ b/src/add-ons/kernel/drivers/disk/usb/usb_disk/usb_disk.cpp @@ -1,18 +1,23 @@ /* - * Copyright 2008-2010, Haiku Inc. All rights reserved. + * Copyright 2008-2012, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Michael Lotz */ -#include -#include -#include -#include -#include -#include + #include "usb_disk.h" + +#include +#include + +#include +#include +#include + +#include + #include "usb_disk_scsi.h" @@ -463,7 +468,7 @@ usb_disk_request_sense(device_lun *lun) TRACE_ALWAYS("request_sense: media changed\n"); lun->media_changed = true; lun->media_present = true; - + return B_DEV_MEDIA_CHANGED; } // fall through @@ -1058,17 +1063,17 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length) break; } - device_geometry *geometry = (device_geometry *)buffer; - geometry->bytes_per_sector = lun->block_size; - geometry->cylinder_count = lun->block_count; - geometry->sectors_per_track = geometry->head_count = 1; - geometry->device_type = lun->device_type; - geometry->removable = lun->removable; - geometry->read_only = lun->write_protected; - geometry->write_once = (lun->device_type == B_WORM); + device_geometry geometry; + devfs_compute_geometry_size(&geometry, lun->block_count, + lun->block_size); + + geometry.device_type = lun->device_type; + geometry.removable = lun->removable; + geometry.read_only = lun->write_protected; + geometry.write_once = lun->device_type == B_WORM; TRACE("B_GET_GEOMETRY: %ld sectors at %ld bytes per sector\n", - geometry->cylinder_count, geometry->bytes_per_sector); - result = B_OK; + geometry.cylinder_count, geometry.bytes_per_sector); + result = user_memcpy(buffer, &geometry, sizeof(device_geometry)); break; } diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index a1e0411138..ba3a113a4a 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2012, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1498,17 +1499,16 @@ devfs_ioctl(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, uint32 op, device_geometry geometry; status_t status = vnode->stream.u.dev.device->Control( cookie->device_cookie, op, &geometry, length); - if (status < B_OK) + if (status != B_OK) return status; // patch values to match partition size - geometry.sectors_per_track = 0; if (geometry.bytes_per_sector == 0) geometry.bytes_per_sector = 512; - geometry.sectors_per_track = partition->info.size - / geometry.bytes_per_sector; - geometry.head_count = 1; - geometry.cylinder_count = 1; + + devfs_compute_geometry_size(&geometry, + partition->info.size / geometry.bytes_per_sector, + geometry.bytes_per_sector); return user_memcpy(buffer, &geometry, sizeof(device_geometry)); } @@ -2207,6 +2207,21 @@ devfs_unpublish_device(BaseDevice* device, bool disconnect) } +void +devfs_compute_geometry_size(device_geometry* geometry, uint64 blockCount, + uint32 blockSize) +{ + if (blockCount > UINT32_MAX) + geometry->head_count = (blockCount + UINT32_MAX - 1) / UINT32_MAX; + else + geometry->head_count = 1; + + geometry->cylinder_count = 1; + geometry->sectors_per_track = blockCount / geometry->head_count; + geometry->bytes_per_sector = blockSize; +} + + // #pragma mark - support API for legacy drivers