1 /* 2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/usb/usbstor/misc.c 5 * PURPOSE: USB block storage device driver. 6 * PROGRAMMERS: 7 * James Tabor 8 * Michael Martin (michael.martin@reactos.org) 9 * Johannes Anderwald (johannes.anderwald@reactos.org) 10 */ 11 12 #include "usbstor.h" 13 14 #define NDEBUG 15 #include <debug.h> 16 17 // 18 // driver verifier 19 // 20 IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine; 21 22 NTSTATUS 23 NTAPI 24 USBSTOR_SyncForwardIrpCompletionRoutine( 25 PDEVICE_OBJECT DeviceObject, 26 PIRP Irp, 27 PVOID Context) 28 { 29 if (Irp->PendingReturned) 30 { 31 KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); 32 } 33 return STATUS_MORE_PROCESSING_REQUIRED; 34 } 35 36 NTSTATUS 37 NTAPI 38 USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp) 39 { 40 KEVENT Event; 41 NTSTATUS Status; 42 43 // 44 // initialize event 45 // 46 KeInitializeEvent(&Event, NotificationEvent, FALSE); 47 48 // 49 // copy irp stack location 50 // 51 IoCopyCurrentIrpStackLocationToNext(Irp); 52 53 // 54 // set completion routine 55 // 56 IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); 57 58 // 59 // call driver 60 // 61 Status = IoCallDriver(DeviceObject, Irp); 62 63 // 64 // check if pending 65 // 66 if (Status == STATUS_PENDING) 67 { 68 // 69 // wait for the request to finish 70 // 71 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 72 73 // 74 // copy status code 75 // 76 Status = Irp->IoStatus.Status; 77 } 78 79 // 80 // done 81 // 82 return Status; 83 } 84 85 NTSTATUS 86 NTAPI 87 USBSTOR_GetBusInterface( 88 IN PDEVICE_OBJECT DeviceObject, 89 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface) 90 { 91 KEVENT Event; 92 NTSTATUS Status; 93 PIRP Irp; 94 IO_STATUS_BLOCK IoStatus; 95 PIO_STACK_LOCATION Stack; 96 97 // 98 // sanity checks 99 // 100 ASSERT(DeviceObject); 101 ASSERT(BusInterface); 102 103 // 104 // initialize event 105 // 106 KeInitializeEvent(&Event, NotificationEvent, FALSE); 107 108 // 109 // create irp 110 // 111 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, 112 DeviceObject, 113 NULL, 114 0, 115 NULL, 116 &Event, 117 &IoStatus); 118 119 // 120 // was irp built 121 // 122 if (Irp == NULL) 123 { 124 // 125 // no memory 126 // 127 return STATUS_INSUFFICIENT_RESOURCES; 128 } 129 130 // 131 // initialize request 132 // 133 Stack=IoGetNextIrpStackLocation(Irp); 134 Stack->MajorFunction = IRP_MJ_PNP; 135 Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; 136 Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); 137 Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&USB_BUS_INTERFACE_USBDI_GUID; 138 Stack->Parameters.QueryInterface.Version = 2; 139 Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface; 140 Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; 141 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 142 143 // 144 // call driver 145 // 146 Status= IoCallDriver(DeviceObject, Irp); 147 148 // 149 // did operation complete 150 // 151 if (Status == STATUS_PENDING) 152 { 153 // 154 // wait for completion 155 // 156 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 157 158 // 159 // collect status 160 // 161 Status=IoStatus.Status; 162 } 163 164 return Status; 165 } 166 167 NTSTATUS 168 USBSTOR_SyncUrbRequest( 169 IN PDEVICE_OBJECT DeviceObject, 170 OUT PURB UrbRequest) 171 { 172 PIRP Irp; 173 PIO_STACK_LOCATION IoStack; 174 KEVENT Event; 175 NTSTATUS Status; 176 177 // 178 // allocate irp 179 // 180 Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); 181 if (!Irp) 182 { 183 // 184 // no memory 185 // 186 return STATUS_INSUFFICIENT_RESOURCES; 187 } 188 189 // 190 // initialize event 191 // 192 KeInitializeEvent(&Event, NotificationEvent, FALSE); 193 194 // 195 // get next stack location 196 // 197 IoStack = IoGetNextIrpStackLocation(Irp); 198 199 // 200 // initialize stack location 201 // 202 IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; 203 IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; 204 IoStack->Parameters.Others.Argument1 = (PVOID)UrbRequest; 205 IoStack->Parameters.DeviceIoControl.InputBufferLength = UrbRequest->UrbHeader.Length; 206 Irp->IoStatus.Status = STATUS_SUCCESS; 207 208 // 209 // setup completion routine 210 // 211 IoSetCompletionRoutine(Irp, USBSTOR_SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE); 212 213 // 214 // call driver 215 // 216 Status = IoCallDriver(DeviceObject, Irp); 217 218 // 219 // check if request is pending 220 // 221 if (Status == STATUS_PENDING) 222 { 223 // 224 // wait for completion 225 // 226 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 227 228 // 229 // update status 230 // 231 Status = Irp->IoStatus.Status; 232 } 233 234 // 235 // free irp 236 // 237 IoFreeIrp(Irp); 238 239 // 240 // done 241 // 242 return Status; 243 } 244 245 PVOID 246 AllocateItem( 247 IN POOL_TYPE PoolType, 248 IN ULONG ItemSize) 249 { 250 // 251 // allocate, zero and return item 252 // 253 return ExAllocatePoolZero(PoolType, ItemSize, USB_STOR_TAG); 254 } 255 256 VOID 257 FreeItem( 258 IN PVOID Item) 259 { 260 // 261 // free item 262 // 263 ExFreePoolWithTag(Item, USB_STOR_TAG); 264 } 265 266 NTSTATUS 267 USBSTOR_ClassRequest( 268 IN PDEVICE_OBJECT DeviceObject, 269 IN PFDO_DEVICE_EXTENSION DeviceExtension, 270 IN UCHAR RequestType, 271 IN USHORT Index, 272 IN ULONG TransferFlags, 273 IN ULONG TransferBufferLength, 274 IN PVOID TransferBuffer) 275 276 { 277 PURB Urb; 278 NTSTATUS Status; 279 280 // 281 // first allocate urb 282 // 283 Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); 284 if (!Urb) 285 { 286 // 287 // no memory 288 // 289 return STATUS_INSUFFICIENT_RESOURCES; 290 } 291 292 // 293 // initialize vendor request 294 // 295 Urb->UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); 296 Urb->UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_CLASS_INTERFACE; 297 Urb->UrbControlVendorClassRequest.TransferFlags = TransferFlags; 298 Urb->UrbControlVendorClassRequest.TransferBufferLength = TransferBufferLength; 299 Urb->UrbControlVendorClassRequest.TransferBuffer = TransferBuffer; 300 Urb->UrbControlVendorClassRequest.Request = RequestType; 301 Urb->UrbControlVendorClassRequest.Index = Index; 302 303 // 304 // submit request 305 // 306 Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); 307 308 // 309 // free urb 310 // 311 FreeItem(Urb); 312 313 // 314 // done 315 // 316 return Status; 317 } 318 319 NTSTATUS 320 USBSTOR_GetMaxLUN( 321 IN PDEVICE_OBJECT DeviceObject, 322 IN PFDO_DEVICE_EXTENSION DeviceExtension) 323 { 324 PUCHAR Buffer; 325 NTSTATUS Status; 326 327 // 328 // allocate 1-byte buffer 329 // 330 Buffer = (PUCHAR)AllocateItem(NonPagedPool, sizeof(UCHAR)); 331 if (!Buffer) 332 { 333 // 334 // no memory 335 // 336 FreeItem(Buffer); 337 return STATUS_INSUFFICIENT_RESOURCES; 338 } 339 340 // 341 // execute request 342 // 343 Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_GET_MAX_LUN, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_IN, sizeof(UCHAR), Buffer); 344 345 DPRINT("MaxLUN: %x\n", *Buffer); 346 347 if (NT_SUCCESS(Status)) 348 { 349 if (*Buffer > 0xF) 350 { 351 // 352 // invalid response documented in usb mass storage specification 353 // 354 Status = STATUS_DEVICE_DATA_ERROR; 355 } 356 else 357 { 358 // 359 // store maxlun 360 // 361 DeviceExtension->MaxLUN = *Buffer; 362 } 363 } 364 else 365 { 366 // 367 // "USB Mass Storage Class. Bulk-Only Transport. Revision 1.0" 368 // 3.2 Get Max LUN (class-specific request) : 369 // Devices that do not support multiple LUNs may STALL this command. 370 // 371 USBSTOR_ResetDevice(DeviceExtension->LowerDeviceObject, DeviceExtension); 372 373 DeviceExtension->MaxLUN = 0; 374 Status = STATUS_SUCCESS; 375 } 376 377 // 378 // free buffer 379 // 380 FreeItem(Buffer); 381 382 // 383 // done 384 // 385 return Status; 386 387 } 388 389 NTSTATUS 390 USBSTOR_ResetDevice( 391 IN PDEVICE_OBJECT DeviceObject, 392 IN PFDO_DEVICE_EXTENSION DeviceExtension) 393 { 394 NTSTATUS Status; 395 396 // 397 // execute request 398 // 399 Status = USBSTOR_ClassRequest(DeviceObject, DeviceExtension, USB_BULK_RESET_DEVICE, DeviceExtension->InterfaceInformation->InterfaceNumber, USBD_TRANSFER_DIRECTION_OUT, 0, NULL); 400 401 // 402 // done 403 // 404 return Status; 405 406 } 407 408 BOOLEAN 409 USBSTOR_IsFloppy( 410 IN PUCHAR Buffer, 411 IN ULONG BufferLength, 412 OUT PUCHAR MediumTypeCode) 413 { 414 PUFI_CAPACITY_FORMAT_HEADER FormatHeader; 415 PUFI_CAPACITY_DESCRIPTOR Descriptor; 416 ULONG Length, Index, BlockCount, BlockLength; 417 418 // 419 // get format header 420 // 421 FormatHeader = (PUFI_CAPACITY_FORMAT_HEADER)Buffer; 422 423 // 424 // sanity checks 425 // 426 ASSERT(FormatHeader->Reserved1 == 0x00); 427 ASSERT(FormatHeader->Reserved2 == 0x00); 428 ASSERT(FormatHeader->Reserved3 == 0x00); 429 430 // 431 // is there capacity data 432 // 433 if (!FormatHeader->CapacityLength) 434 { 435 // 436 // no data provided 437 // 438 DPRINT1("[USBSTOR] No capacity length\n"); 439 return FALSE; 440 } 441 442 // 443 // the format header are always 8 bytes in length 444 // 445 ASSERT((FormatHeader->CapacityLength & 0x7) == 0); 446 DPRINT1("CapacityLength %x\n", FormatHeader->CapacityLength); 447 448 // 449 // grab length and locate first descriptor 450 // 451 Length = FormatHeader->CapacityLength; 452 Descriptor = (PUFI_CAPACITY_DESCRIPTOR)(FormatHeader + 1); 453 for(Index = 0; Index < Length / sizeof(UFI_CAPACITY_DESCRIPTOR); Index++) 454 { 455 // 456 // blocks are little endian format 457 // 458 BlockCount = NTOHL(Descriptor->BlockCount); 459 460 // 461 // get block length 462 // 463 BlockLength = NTOHL((Descriptor->BlockLengthByte0 << 24 | Descriptor->BlockLengthByte1 << 16 | Descriptor->BlockLengthByte2 << 8)); 464 465 DPRINT1("BlockCount %x BlockLength %x Code %x\n", BlockCount, BlockLength, Descriptor->Code); 466 467 if (BlockLength == 512 && BlockCount == 1440) 468 { 469 // 470 // 720 KB DD 471 // 472 *MediumTypeCode = 0x1E; 473 return TRUE; 474 } 475 else if (BlockLength == 1024 && BlockCount == 1232) 476 { 477 // 478 // 1,25 MB 479 // 480 *MediumTypeCode = 0x93; 481 return TRUE; 482 } 483 else if (BlockLength == 512 && BlockCount == 2880) 484 { 485 // 486 // 1,44MB KB DD 487 // 488 *MediumTypeCode = 0x94; 489 return TRUE; 490 } 491 492 // 493 // move to next descriptor 494 // 495 Descriptor = (Descriptor + 1); 496 } 497 498 // 499 // no floppy detected 500 // 501 return FALSE; 502 } 503