1 /* 2 * Copyright 2018 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * B Krishnan Iyer, krishnaniyer97@gmail.com 7 */ 8 #include <string.h> 9 #include <stdlib.h> 10 #include <stdio.h> 11 #include <ctype.h> 12 #include "mmc_disk.h" 13 14 #include <drivers/device_manager.h> 15 #include <drivers/KernelExport.h> 16 #include <drivers/Drivers.h> 17 #include <kernel/OS.h> 18 19 // #include <fs/devfs.h> 20 21 #define TRACE_MMC_DISK 22 #ifdef TRACE_MMC_DISK 23 # define TRACE(x...) dprintf("mmc_disk: " x) 24 #else 25 # define TRACE(x...) ; 26 #endif 27 #define ERROR(x...) dprintf("\33[33mmc_disk:\33[0m " x) 28 #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 29 30 #define MMC_DISK_DRIVER_MODULE_NAME "drivers/disk/mmc/mmc_disk/driver_v1" 31 #define MMC_DISK_DEVICE_MODULE_NAME "drivers/disk/mmc/mmc_disk/device_v1" 32 #define MMC_DEVICE_ID_GENERATOR "mmc/device_id" 33 34 static device_manager_info* sDeviceManager; 35 36 37 static float 38 mmc_disk_supports_device(device_node* parent) 39 { 40 CALLED(); 41 const char* bus; 42 // uint16 deviceType; 43 44 if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, 45 true) != B_OK) 46 return -1; 47 48 if (strcmp(bus, "mmc") != 0) { 49 TRACE("bus value %s, parent: %p\n",bus, parent); 50 return 0.0; 51 } 52 // Used to check the device type but later we have attached an 53 // attribute(mmc) to the bus. Not a compulsion to use this condition 54 #if 0 55 if (sDeviceManager->get_attr_uint16(parent, SDHCI_DEVICE_TYPE_ITEM, 56 &deviceType, true) != B_OK) 57 { 58 TRACE(" Inavlid device type, bus found: %s and attr val %d\n", 59 bus, deviceType); 60 return 0.0; 61 } 62 #endif 63 TRACE("sdhci device found, parent: %p\n", parent); 64 65 return 0.8; 66 } 67 68 69 static status_t 70 mmc_disk_register_device(device_node* node) 71 { 72 CALLED(); 73 74 device_attr attrs[] = { 75 { NULL } 76 }; 77 78 return sDeviceManager->register_node(node 79 , MMC_DISK_DRIVER_MODULE_NAME, attrs, NULL, NULL); 80 } 81 82 83 static status_t 84 mmc_disk_init_driver(device_node* node, void** cookie) 85 { 86 CALLED(); 87 mmc_disk_driver_info* info = (mmc_disk_driver_info*)malloc( 88 sizeof(mmc_disk_driver_info)); 89 90 if (info == NULL) 91 return B_NO_MEMORY; 92 93 memset(info, 0, sizeof(*info)); 94 95 info->node = node; 96 97 *cookie = info; 98 return B_OK; 99 } 100 101 102 static void 103 mmc_disk_uninit_driver(void* _cookie) 104 { 105 CALLED(); 106 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie; 107 free(info); 108 } 109 110 111 static status_t 112 mmc_disk_register_child_devices(void* _cookie) 113 { 114 CALLED(); 115 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie; 116 status_t status; 117 118 int32 id = sDeviceManager->create_id(MMC_DEVICE_ID_GENERATOR); 119 if (id < 0) 120 return id; 121 122 char name[64]; 123 snprintf(name, sizeof(name), "disk/mmc/%" B_PRId32 "/raw", id); 124 125 status = sDeviceManager->publish_device(info->node, name, 126 MMC_DISK_DEVICE_MODULE_NAME); 127 128 return status; 129 } 130 131 132 module_dependency module_dependencies[] = { 133 {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager}, 134 {} 135 }; 136 137 138 struct driver_module_info sMMCDiskDriver = { 139 { 140 MMC_DISK_DRIVER_MODULE_NAME, 141 0, 142 NULL 143 }, 144 mmc_disk_supports_device, 145 mmc_disk_register_device, 146 mmc_disk_init_driver, 147 mmc_disk_uninit_driver, 148 mmc_disk_register_child_devices, 149 NULL, // mmc_disk_rescan_child_devices, 150 NULL, 151 }; 152 153 154 module_info* modules[] = { 155 (module_info*)&sMMCDiskDriver, 156 NULL 157 }; 158