static status_t usb_disk_write(void *cookie, off_t position, const void *buffer, size_t *length) { if (buffer == NULL || length == NULL) return B_BAD_VALUE; TRACE("write(%lld, %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); if (device->removed) { *length = 0; mutex_unlock(&device->lock); return B_DEV_NOT_READY; } status_t result = B_ERROR; uint32 blockPosition = 0; uint16 blockCount = 0; bool needsPartial = usb_disk_needs_partial_buffer(lun, position, *length, blockPosition, blockCount); if (needsPartial) { void *partialBuffer = NULL; void *blockBuffer = NULL; result = usb_disk_prepare_partial_buffer(lun, position, *length, partialBuffer, blockBuffer, blockPosition, blockCount); if (result == B_OK) { memcpy(partialBuffer, buffer, *length); size_t blockLength = blockCount * lun->block_size; result = usb_disk_block_write(lun, blockPosition, blockCount, blockBuffer, &blockLength); free(blockBuffer); } } else { result = usb_disk_block_write(lun, blockPosition, blockCount, (void *)buffer, length); } mutex_unlock(&device->lock); if (result == B_OK) { TRACE("write successful with %ld bytes\n", *length); return B_OK; } *length = 0; TRACE_ALWAYS("write fails with 0x%08lx\n", result); return result; }
static status_t usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length) { if (buffer == NULL || length == NULL) return B_BAD_VALUE; TRACE("read(%" B_PRIdOFF ", %ld)\n", position, *length); device_lun *lun = (device_lun *)cookie; disk_device *device = lun->device; mutex_lock(&device->lock); if (device->removed) { *length = 0; mutex_unlock(&device->lock); return B_DEV_NOT_READY; } status_t result = B_ERROR; uint32 blockPosition = 0; uint16 blockCount = 0; bool needsPartial = usb_disk_needs_partial_buffer(lun, position, *length, blockPosition, blockCount); if (needsPartial) { void *partialBuffer = NULL; void *blockBuffer = NULL; result = usb_disk_prepare_partial_buffer(lun, position, *length, partialBuffer, blockBuffer, blockPosition, blockCount); if (result == B_OK) { memcpy(buffer, partialBuffer, *length); free(blockBuffer); } } else { result = usb_disk_block_read(lun, blockPosition, blockCount, buffer, length); } mutex_unlock(&device->lock); if (result == B_OK) { TRACE("read successful with %ld bytes\n", *length); return B_OK; } *length = 0; TRACE_ALWAYS("read failed: %s\n", strerror(result)); return result; }