1 /* 2 * Copyright 2018-2021 Haiku, Inc. All rights reserved. 3 * Copyright 2020, Viveris Technologies. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * B Krishnan Iyer, krishnaniyer97@gmail.com 8 * Adrien Destugues, pulkomandy@pulkomandy.tk 9 */ 10 11 #include <new> 12 13 #include <ctype.h> 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <string.h> 17 18 #include "mmc_disk.h" 19 #include "mmc_icon.h" 20 #include "mmc.h" 21 22 #include <drivers/device_manager.h> 23 #include <drivers/KernelExport.h> 24 #include <drivers/Drivers.h> 25 #include <kernel/OS.h> 26 #include <util/fs_trim_support.h> 27 28 #include <AutoDeleter.h> 29 30 31 #define TRACE_MMC_DISK 32 #ifdef TRACE_MMC_DISK 33 # define TRACE(x...) dprintf("\33[33mmmc_disk:\33[0m " x) 34 #else 35 # define TRACE(x...) ; 36 #endif 37 #define ERROR(x...) dprintf("\33[33mmmc_disk:\33[0m " x) 38 #define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__) 39 40 #define MMC_DISK_DRIVER_MODULE_NAME "drivers/disk/mmc/mmc_disk/driver_v1" 41 #define MMC_DISK_DEVICE_MODULE_NAME "drivers/disk/mmc/mmc_disk/device_v1" 42 #define MMC_DEVICE_ID_GENERATOR "mmc/device_id" 43 44 45 static const uint32 kBlockSize = 512; // FIXME get it from the CSD 46 47 static device_manager_info* sDeviceManager; 48 49 50 struct mmc_disk_csd { 51 // The content of this register is described in Physical Layer Simplified 52 // Specification Version 8.00, section 5.3 53 uint64 bits[2]; 54 55 uint8 structure_version() { return bits[1] >> 54; } 56 uint8 read_bl_len() { return (bits[1] >> 8) & 0xF; } 57 uint32 c_size() 58 { 59 if (structure_version() == 0) 60 return ((bits[0] >> 54) & 0x3FF) | ((bits[1] & 0x3) << 10); 61 if (structure_version() == 1) 62 return (bits[0] >> 40) & 0x3FFFFF; 63 return ((bits[0] >> 40) & 0xFFFFFF) | ((bits[1] & 0xF) << 24); 64 } 65 66 uint8 c_size_mult() 67 { 68 if (structure_version() == 0) 69 return (bits[0] >> 39) & 0x7; 70 // In later versions this field is not present in the structure and a 71 // fixed value is used. 72 return 8; 73 } 74 }; 75 76 77 static float 78 mmc_disk_supports_device(device_node* parent) 79 { 80 // Filter all devices that are not on an MMC bus 81 const char* bus; 82 if (sDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, 83 true) != B_OK) 84 return -1; 85 86 if (strcmp(bus, "mmc") != 0) 87 return 0.0; 88 89 CALLED(); 90 91 // Filter all devices that are not of the known types 92 uint8_t deviceType; 93 if (sDeviceManager->get_attr_uint8(parent, kMmcTypeAttribute, 94 &deviceType, true) != B_OK) 95 { 96 ERROR("Could not get device type\n"); 97 return -1; 98 } 99 100 if (deviceType == CARD_TYPE_SD) 101 TRACE("SD card found, parent: %p\n", parent); 102 else if (deviceType == CARD_TYPE_SDHC) 103 TRACE("SDHC card found, parent: %p\n", parent); 104 else 105 return 0.0; 106 107 return 0.8; 108 } 109 110 111 static status_t 112 mmc_disk_register_device(device_node* node) 113 { 114 CALLED(); 115 116 device_attr attrs[] = { 117 { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "SD Card" }}, 118 { NULL } 119 }; 120 121 return sDeviceManager->register_node(node, MMC_DISK_DRIVER_MODULE_NAME, 122 attrs, NULL, NULL); 123 } 124 125 126 static status_t 127 mmc_disk_execute_iorequest(void* data, IOOperation* operation) 128 { 129 mmc_disk_driver_info* info = (mmc_disk_driver_info*)data; 130 status_t error; 131 132 uint8_t command; 133 if (operation->IsWrite()) 134 command = SD_WRITE_MULTIPLE_BLOCKS; 135 else 136 command = SD_READ_MULTIPLE_BLOCKS; 137 error = info->mmc->do_io(info->parent, info->parentCookie, info->rca, 138 command, operation, (info->flags & kIoCommandOffsetAsSectors) != 0); 139 140 if (error != B_OK) { 141 info->scheduler->OperationCompleted(operation, error, 0); 142 return error; 143 } 144 145 info->scheduler->OperationCompleted(operation, B_OK, operation->Length()); 146 return B_OK; 147 } 148 149 150 static status_t 151 mmc_block_get_geometry(mmc_disk_driver_info* info, device_geometry* geometry) 152 { 153 struct mmc_disk_csd csd; 154 TRACE("Get geometry\n"); 155 status_t error = info->mmc->execute_command(info->parent, 156 info->parentCookie, 0, SD_SEND_CSD, info->rca << 16, (uint32_t*)&csd); 157 if (error != B_OK) { 158 TRACE("Could not get CSD! %s\n", strerror(error)); 159 return error; 160 } 161 162 TRACE("CSD: %" PRIx64 " %" PRIx64 "\n", csd.bits[0], csd.bits[1]); 163 164 if (csd.structure_version() >= 3) { 165 TRACE("unknown CSD version %d\n", csd.structure_version()); 166 return B_NOT_SUPPORTED; 167 } 168 169 geometry->bytes_per_sector = 1 << csd.read_bl_len(); 170 geometry->sectors_per_track = csd.c_size() + 1; 171 geometry->cylinder_count = 1 << (csd.c_size_mult() + 2); 172 geometry->head_count = 1; 173 geometry->device_type = B_DISK; 174 geometry->removable = true; // TODO detect eMMC which isn't 175 geometry->read_only = false; // TODO check write protect switch? 176 geometry->write_once = false; 177 178 // This function will be called before all data transfers, so we use this 179 // opportunity to switch the card to 4-bit data transfers (instead of the 180 // default 1 bit mode) 181 uint32_t cardStatus; 182 const uint32 k4BitMode = 2; 183 info->mmc->execute_command(info->parent, info->parentCookie, info->rca, 184 SD_APP_CMD, info->rca << 16, &cardStatus); 185 info->mmc->execute_command(info->parent, info->parentCookie, info->rca, 186 SD_SET_BUS_WIDTH, k4BitMode, &cardStatus); 187 188 // From now on we use 4 bit mode 189 info->mmc->set_bus_width(info->parent, info->parentCookie, 4); 190 191 return B_OK; 192 } 193 194 195 static status_t 196 mmc_disk_init_driver(device_node* node, void** cookie) 197 { 198 CALLED(); 199 mmc_disk_driver_info* info = (mmc_disk_driver_info*)malloc( 200 sizeof(mmc_disk_driver_info)); 201 202 if (info == NULL) 203 return B_NO_MEMORY; 204 205 memset(info, 0, sizeof(*info)); 206 207 void* unused2; 208 info->node = node; 209 info->parent = sDeviceManager->get_parent_node(info->node); 210 sDeviceManager->get_driver(info->parent, (driver_module_info **)&info->mmc, 211 &unused2); 212 213 // We need to grab the bus cookie as well 214 // FIXME it would be easier if that was available from the get_driver call 215 // above directly, but currently it isn't. 216 device_node* busNode = sDeviceManager->get_parent_node(info->parent); 217 driver_module_info* unused; 218 sDeviceManager->get_driver(busNode, &unused, &info->parentCookie); 219 sDeviceManager->put_node(busNode); 220 221 TRACE("MMC bus handle: %p %s\n", info->mmc, info->mmc->info.info.name); 222 223 if (sDeviceManager->get_attr_uint16(node, kMmcRcaAttribute, &info->rca, 224 true) != B_OK) { 225 TRACE("MMC card node has no RCA attribute\n"); 226 free(info); 227 return B_BAD_DATA; 228 } 229 230 uint8_t deviceType; 231 if (sDeviceManager->get_attr_uint8(info->parent, kMmcTypeAttribute, 232 &deviceType, true) != B_OK) { 233 ERROR("Could not get device type\n"); 234 free(info); 235 return B_BAD_DATA; 236 } 237 238 // SD and MMC cards use byte offsets for IO commands, later ones (SDHC, 239 // SDXC, ...) use sectors. 240 if (deviceType == CARD_TYPE_SD || deviceType == CARD_TYPE_MMC) 241 info->flags = 0; 242 else 243 info->flags = kIoCommandOffsetAsSectors; 244 245 status_t error; 246 247 static const uint32 kDMAResourceBufferCount = 16; 248 static const uint32 kDMAResourceBounceBufferCount = 16; 249 250 info->dmaResource = new(std::nothrow) DMAResource; 251 if (info->dmaResource == NULL) { 252 TRACE("Failed to allocate DMA resource"); 253 free(info); 254 return B_NO_MEMORY; 255 } 256 257 error = info->dmaResource->Init(info->node, kBlockSize, 258 kDMAResourceBufferCount, kDMAResourceBounceBufferCount); 259 if (error != B_OK) { 260 TRACE("Failed to init DMA resource"); 261 delete info->dmaResource; 262 free(info); 263 return error; 264 } 265 266 info->scheduler = new(std::nothrow) IOSchedulerSimple(info->dmaResource); 267 if (info->scheduler == NULL) { 268 TRACE("Failed to allocate scheduler"); 269 delete info->dmaResource; 270 free(info); 271 return B_NO_MEMORY; 272 } 273 274 error = info->scheduler->Init("mmc storage"); 275 if (error != B_OK) { 276 TRACE("Failed to init scheduler"); 277 delete info->scheduler; 278 delete info->dmaResource; 279 free(info); 280 return error; 281 } 282 info->scheduler->SetCallback(&mmc_disk_execute_iorequest, info); 283 284 memset(&info->geometry, 0, sizeof(info->geometry)); 285 286 TRACE("MMC card device initialized for RCA %x\n", info->rca); 287 *cookie = info; 288 return B_OK; 289 } 290 291 292 static void 293 mmc_disk_uninit_driver(void* _cookie) 294 { 295 CALLED(); 296 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie; 297 delete info->scheduler; 298 delete info->dmaResource; 299 sDeviceManager->put_node(info->parent); 300 free(info); 301 } 302 303 304 static status_t 305 mmc_disk_register_child_devices(void* _cookie) 306 { 307 CALLED(); 308 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie; 309 status_t status; 310 311 int32 id = sDeviceManager->create_id(MMC_DEVICE_ID_GENERATOR); 312 if (id < 0) 313 return id; 314 315 char name[64]; 316 snprintf(name, sizeof(name), "disk/mmc/%" B_PRId32 "/raw", id); 317 318 status = sDeviceManager->publish_device(info->node, name, 319 MMC_DISK_DEVICE_MODULE_NAME); 320 321 return status; 322 } 323 324 325 // #pragma mark - device module API 326 327 328 static status_t 329 mmc_block_init_device(void* _info, void** _cookie) 330 { 331 CALLED(); 332 333 // No additional context, so just reuse the same data as the disk device 334 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_info; 335 *_cookie = info; 336 337 // Note: it is not possible to execute commands here, because this is called 338 // with the mmc_bus locked for enumeration (and still using slow clock). 339 340 return B_OK; 341 } 342 343 344 static void 345 mmc_block_uninit_device(void* _cookie) 346 { 347 CALLED(); 348 //mmc_disk_driver_info* info = (mmc_disk_driver_info*)_cookie; 349 350 // TODO cleanup whatever is relevant 351 } 352 353 354 static status_t 355 mmc_block_open(void* _info, const char* path, int openMode, void** _cookie) 356 { 357 CALLED(); 358 mmc_disk_driver_info* info = (mmc_disk_driver_info*)_info; 359 360 // allocate cookie 361 mmc_disk_handle* handle = new(std::nothrow) mmc_disk_handle; 362 *_cookie = handle; 363 if (handle == NULL) { 364 return B_NO_MEMORY; 365 } 366 handle->info = info; 367 368 return B_OK; 369 } 370 371 372 static status_t 373 mmc_block_close(void* cookie) 374 { 375 //mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 376 CALLED(); 377 378 return B_OK; 379 } 380 381 382 static status_t 383 mmc_block_free(void* cookie) 384 { 385 CALLED(); 386 mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 387 388 delete handle; 389 return B_OK; 390 } 391 392 393 static status_t 394 mmc_block_read(void* cookie, off_t pos, void* buffer, size_t* _length) 395 { 396 CALLED(); 397 mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 398 399 size_t length = *_length; 400 401 if (handle->info->geometry.bytes_per_sector == 0) { 402 status_t error = mmc_block_get_geometry(handle->info, 403 &handle->info->geometry); 404 if (error != B_OK) { 405 TRACE("Failed to get disk capacity"); 406 return error; 407 } 408 } 409 410 // Do not allow reading past device end 411 if (pos >= handle->info->DeviceSize()) 412 return B_BAD_VALUE; 413 if (pos + (off_t)length > handle->info->DeviceSize()) 414 length = handle->info->DeviceSize() - pos; 415 416 IORequest request; 417 status_t status = request.Init(pos, (addr_t)buffer, length, false, 0); 418 if (status != B_OK) 419 return status; 420 421 status = handle->info->scheduler->ScheduleRequest(&request); 422 if (status != B_OK) 423 return status; 424 425 status = request.Wait(0, 0); 426 if (status == B_OK) 427 *_length = length; 428 return status; 429 } 430 431 432 static status_t 433 mmc_block_write(void* cookie, off_t position, const void* buffer, 434 size_t* _length) 435 { 436 CALLED(); 437 mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 438 439 size_t length = *_length; 440 441 if (handle->info->geometry.bytes_per_sector == 0) { 442 status_t error = mmc_block_get_geometry(handle->info, 443 &handle->info->geometry); 444 if (error != B_OK) { 445 TRACE("Failed to get disk capacity"); 446 return error; 447 } 448 } 449 450 if (position >= handle->info->DeviceSize()) 451 return B_BAD_VALUE; 452 if (position + (off_t)length > handle->info->DeviceSize()) 453 length = handle->info->DeviceSize() - position; 454 455 IORequest request; 456 status_t status = request.Init(position, (addr_t)buffer, length, true, 0); 457 if (status != B_OK) 458 return status; 459 460 status = handle->info->scheduler->ScheduleRequest(&request); 461 if (status != B_OK) 462 return status; 463 464 status = request.Wait(0, 0); 465 if (status == B_OK) 466 *_length = length; 467 468 return status; 469 } 470 471 472 static status_t 473 mmc_block_io(void* cookie, io_request* request) 474 { 475 CALLED(); 476 mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 477 478 return handle->info->scheduler->ScheduleRequest(request); 479 } 480 481 482 static status_t 483 mmc_block_trim(mmc_disk_driver_info* info, fs_trim_data* trimData) 484 { 485 enum { 486 kEraseModeErase = 0, // force to actually erase the data 487 kEraseModeDiscard = 1, 488 // just mark the data as unused for internal wear leveling 489 // algorithms 490 kEraseModeFullErase = 2, // erase the whole card 491 }; 492 TRACE("trim_device()\n"); 493 494 trimData->trimmed_size = 0; 495 496 const off_t deviceSize = info->DeviceSize(); // in bytes 497 if (deviceSize < 0) 498 return B_BAD_VALUE; 499 500 STATIC_ASSERT(sizeof(deviceSize) <= sizeof(uint64)); 501 ASSERT(deviceSize >= 0); 502 503 // Do not trim past device end 504 for (uint32 i = 0; i < trimData->range_count; i++) { 505 uint64 offset = trimData->ranges[i].offset; 506 uint64& size = trimData->ranges[i].size; 507 508 if (offset >= (uint64)deviceSize) 509 return B_BAD_VALUE; 510 size = min_c(size, (uint64)deviceSize - offset); 511 } 512 513 uint64 trimmedSize = 0; 514 status_t result = B_OK; 515 for (uint32 i = 0; i < trimData->range_count; i++) { 516 uint64 offset = trimData->ranges[i].offset; 517 uint64 length = trimData->ranges[i].size; 518 519 // Round up offset and length to multiple of the sector size 520 // The offset is rounded up, so some space may be left 521 // (not trimmed) at the start of the range. 522 offset = ROUNDUP(offset, kBlockSize); 523 // Adjust the length for the possibly skipped range 524 length -= offset - trimData->ranges[i].offset; 525 // The length is rounded down, so some space at the end may also 526 // be left (not trimmed). 527 length &= ~(kBlockSize - 1); 528 529 if (length == 0) 530 continue; 531 532 TRACE("trim %" B_PRIu64 " bytes from %" B_PRIu64 "\n", 533 length, offset); 534 535 ASSERT(offset % kBlockSize == 0); 536 ASSERT(length % kBlockSize == 0); 537 538 if ((info->flags & kIoCommandOffsetAsSectors) != 0) { 539 offset /= kBlockSize; 540 length /= kBlockSize; 541 } 542 543 // Parameter of execute_command is uint32_t 544 if (offset > UINT32_MAX 545 || length > UINT32_MAX - offset) { 546 result = B_BAD_VALUE; 547 break; 548 } 549 550 uint32_t response; 551 result = info->mmc->execute_command(info->parent, info->parentCookie, 552 info->rca, SD_ERASE_WR_BLK_START, offset, &response); 553 if (result != B_OK) 554 break; 555 result = info->mmc->execute_command(info->parent, info->parentCookie, 556 info->rca, SD_ERASE_WR_BLK_END, offset + length, &response); 557 if (result != B_OK) 558 break; 559 result = info->mmc->execute_command(info->parent, info->parentCookie, 560 info->rca, SD_ERASE, kEraseModeDiscard, &response); 561 if (result != B_OK) 562 break; 563 564 trimmedSize += (info->flags & kIoCommandOffsetAsSectors) != 0 565 ? length * kBlockSize : length; 566 } 567 568 trimData->trimmed_size = trimmedSize; 569 570 return result; 571 } 572 573 574 static status_t 575 mmc_block_ioctl(void* cookie, uint32 op, void* buffer, size_t length) 576 { 577 mmc_disk_handle* handle = (mmc_disk_handle*)cookie; 578 mmc_disk_driver_info* info = handle->info; 579 580 switch (op) { 581 case B_GET_MEDIA_STATUS: 582 { 583 if (buffer == NULL || length < sizeof(status_t)) 584 return B_BAD_VALUE; 585 586 *(status_t *)buffer = B_OK; 587 return B_OK; 588 break; 589 } 590 591 case B_GET_DEVICE_SIZE: 592 { 593 // Legacy ioctl, use B_GET_GEOMETRY 594 if (info->geometry.bytes_per_sector == 0) { 595 status_t error = mmc_block_get_geometry(info, &info->geometry); 596 if (error != B_OK) { 597 TRACE("Failed to get disk capacity"); 598 return error; 599 } 600 } 601 602 uint64_t size = info->DeviceSize(); 603 if (size > SIZE_MAX) 604 return B_NOT_SUPPORTED; 605 size_t size32 = size; 606 return user_memcpy(buffer, &size32, sizeof(size_t)); 607 } 608 609 case B_GET_GEOMETRY: 610 { 611 if (buffer == NULL || length < sizeof(device_geometry)) 612 return B_BAD_VALUE; 613 614 if (info->geometry.bytes_per_sector == 0) { 615 status_t error = mmc_block_get_geometry(info, &info->geometry); 616 if (error != B_OK) { 617 TRACE("Failed to get disk capacity"); 618 return error; 619 } 620 } 621 622 return user_memcpy(buffer, &info->geometry, 623 sizeof(device_geometry)); 624 } 625 626 case B_GET_ICON_NAME: 627 return user_strlcpy((char*)buffer, "devices/drive-harddisk", 628 B_FILE_NAME_LENGTH); 629 630 case B_GET_VECTOR_ICON: 631 { 632 // TODO: take device type into account! 633 device_icon iconData; 634 if (length != sizeof(device_icon)) 635 return B_BAD_VALUE; 636 if (user_memcpy(&iconData, buffer, sizeof(device_icon)) != B_OK) 637 return B_BAD_ADDRESS; 638 639 if (iconData.icon_size >= (int32)sizeof(kDriveIcon)) { 640 if (user_memcpy(iconData.icon_data, kDriveIcon, 641 sizeof(kDriveIcon)) != B_OK) 642 return B_BAD_ADDRESS; 643 } 644 645 iconData.icon_size = sizeof(kDriveIcon); 646 return user_memcpy(buffer, &iconData, sizeof(device_icon)); 647 } 648 649 case B_TRIM_DEVICE: 650 { 651 // We know the buffer is kernel-side because it has been 652 // preprocessed in devfs 653 return mmc_block_trim(info, (fs_trim_data*)buffer); 654 } 655 656 /*case B_FLUSH_DRIVE_CACHE: 657 return synchronize_cache(info);*/ 658 } 659 660 return B_DEV_INVALID_IOCTL; 661 } 662 663 664 module_dependency module_dependencies[] = { 665 {B_DEVICE_MANAGER_MODULE_NAME, (module_info**)&sDeviceManager}, 666 {} 667 }; 668 669 670 // The "block device" associated with the device file. It can be open() 671 // multiple times, eash allocating an mmc_disk_handle. It does not interact 672 // with the hardware directly, instead it forwards all IO requests to the 673 // disk driver through the IO scheduler. 674 struct device_module_info sMMCBlockDevice = { 675 { 676 MMC_DISK_DEVICE_MODULE_NAME, 677 0, 678 NULL 679 }, 680 681 mmc_block_init_device, 682 mmc_block_uninit_device, 683 NULL, // remove, 684 685 mmc_block_open, 686 mmc_block_close, 687 mmc_block_free, 688 mmc_block_read, 689 mmc_block_write, 690 mmc_block_io, 691 mmc_block_ioctl, 692 693 NULL, // select 694 NULL, // deselect 695 }; 696 697 698 // Driver for the disk devices itself. This is paired with an 699 // mmc_disk_driver_info instanciated once per device. Handles the actual disk 700 // I/O operations 701 struct driver_module_info sMMCDiskDriver = { 702 { 703 MMC_DISK_DRIVER_MODULE_NAME, 704 0, 705 NULL 706 }, 707 mmc_disk_supports_device, 708 mmc_disk_register_device, 709 mmc_disk_init_driver, 710 mmc_disk_uninit_driver, 711 mmc_disk_register_child_devices, 712 NULL, // mmc_disk_rescan_child_devices, 713 NULL, 714 }; 715 716 717 module_info* modules[] = { 718 (module_info*)&sMMCDiskDriver, 719 (module_info*)&sMMCBlockDevice, 720 NULL 721 }; 722