1 /* 2 * Copyright 2004-2011, Haiku, Inc. All RightsReserved. 3 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 //! Basic handling of device. 10 11 12 #include "scsi_periph_int.h" 13 14 #include <string.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 18 19 #define SCSI_PERIPH_STD_TIMEOUT 10 20 21 22 char * 23 periph_compose_device_name(device_node *node, const char *prefix) 24 { 25 uint8 pathID, targetID, targetLUN, type; 26 char name[128]; 27 uint32 channel; 28 29 if (gDeviceManager->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &pathID, true) != B_OK 30 || gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TARGET_ID_ITEM, &targetID, true) != B_OK 31 || gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TARGET_LUN_ITEM, &targetLUN, true) != B_OK) 32 return NULL; 33 34 // IDE devices have a different naming scheme 35 36 if (gDeviceManager->get_attr_uint32(node, "ide/channel_id", &channel, true) == B_OK 37 && gDeviceManager->get_attr_uint8(node, SCSI_DEVICE_TYPE_ITEM, &type, true) == B_OK) { 38 // this is actually an IDE device, so we ignore the prefix 39 40 // a bus device for those 41 snprintf(name, sizeof(name), "disk/ata%s/%" B_PRId32 "/%s/raw", 42 type == scsi_dev_CDROM ? "pi" : "", channel, 43 targetID == 0 ? "master" : "slave"); 44 } else { 45 // this is a real SCSI device 46 47 snprintf(name, sizeof(name), "%s/%d/%d/%d/raw", 48 prefix, pathID, targetID, targetLUN); 49 } 50 51 return strdup(name); 52 } 53 54 55 status_t 56 periph_register_device(periph_device_cookie periph_device, 57 scsi_periph_callbacks *callbacks, scsi_device scsi_device, 58 scsi_device_interface *scsi, device_node *node, 59 bool removable, int preferredCcbSize, scsi_periph_device *driver) 60 { 61 SHOW_FLOW0(3, ""); 62 63 scsi_periph_device_info *device 64 = (scsi_periph_device_info *)malloc(sizeof(*device)); 65 if (device == NULL) 66 return B_NO_MEMORY; 67 68 memset(device, 0, sizeof(*device)); 69 70 mutex_init(&device->mutex, "SCSI_PERIPH"); 71 device->scsi_device = scsi_device; 72 device->scsi = scsi; 73 device->periph_device = periph_device; 74 device->removal_requested = false; 75 device->callbacks = callbacks; 76 device->node = node; 77 device->removable = removable; 78 device->std_timeout = SCSI_PERIPH_STD_TIMEOUT; 79 80 // set some default options 81 device->next_tag_action = 0; 82 device->preferred_ccb_size = preferredCcbSize; 83 device->rw10_enabled = true; 84 device->unmap_command = TRIM_NONE; 85 device->max_unmap_lba_count = 0; 86 device->max_unmap_descriptor_count = 0; 87 88 // launch sync daemon 89 status_t status = register_kernel_daemon(periph_sync_queue_daemon, device, 90 60*10); 91 if (status != B_OK) 92 goto err1; 93 94 *driver = device; 95 96 SHOW_FLOW0(3, "done"); 97 98 return B_OK; 99 100 err1: 101 mutex_destroy(&device->mutex); 102 free(device); 103 return status; 104 } 105 106 107 status_t 108 periph_unregister_device(scsi_periph_device_info *device) 109 { 110 unregister_kernel_daemon(periph_sync_queue_daemon, device); 111 free(device); 112 113 return B_OK; 114 } 115