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