1 #ifndef _USBSTOR_H_ 2 #define _USBSTOR_H_ 3 4 #include <wdm.h> 5 #include <usbdi.h> 6 #include <usbbusif.h> 7 #include <usbdlib.h> 8 #include <classpnp.h> 9 10 #define USB_STOR_TAG 'sbsu' 11 #define USB_MAXCHILDREN (16) 12 13 #define HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) 14 #define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8)) 15 16 #define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ 17 ((((unsigned long)(n) & 0xFF00)) << 8) | \ 18 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ 19 ((((unsigned long)(n) & 0xFF000000)) >> 24)) 20 21 22 #define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \ 23 ((((unsigned long)(n) & 0xFF00)) << 8) | \ 24 ((((unsigned long)(n) & 0xFF0000)) >> 8) | \ 25 ((((unsigned long)(n) & 0xFF000000)) >> 24)) 26 27 #define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \ 28 | USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH) 29 30 typedef struct __COMMON_DEVICE_EXTENSION__ 31 { 32 BOOLEAN IsFDO; 33 34 }USBSTOR_COMMON_DEVICE_EXTENSION, *PUSBSTOR_COMMON_DEVICE_EXTENSION; 35 36 typedef struct 37 { 38 USBSTOR_COMMON_DEVICE_EXTENSION Common; // common device extension 39 40 PDEVICE_OBJECT FunctionalDeviceObject; // functional device object 41 PDEVICE_OBJECT PhysicalDeviceObject; // physical device object 42 PDEVICE_OBJECT LowerDeviceObject; // lower device object 43 USB_BUS_INTERFACE_USBDI_V2 BusInterface; // bus interface of device 44 PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor 45 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor 46 PUSB_STRING_DESCRIPTOR SerialNumber; // usb serial number 47 PUSBD_INTERFACE_INFORMATION InterfaceInformation; // usb interface information 48 USBD_CONFIGURATION_HANDLE ConfigurationHandle; // usb configuration handle 49 UCHAR BulkInPipeIndex; // bulk in pipe index 50 UCHAR BulkOutPipeIndex; // bulk out pipe index 51 UCHAR MaxLUN; // max lun for device 52 PDEVICE_OBJECT ChildPDO[16]; // max 16 child pdo devices 53 KSPIN_LOCK IrpListLock; // irp list lock 54 LIST_ENTRY IrpListHead; // irp list head 55 BOOLEAN IrpListFreeze; // if true the irp list is freezed 56 BOOLEAN ResetInProgress; // if hard reset is in progress 57 ULONG IrpPendingCount; // count of irp pending 58 PSCSI_REQUEST_BLOCK ActiveSrb; // stores the current active SRB 59 KEVENT NoPendingRequests; // set if no pending or in progress requests 60 PSCSI_REQUEST_BLOCK LastTimerActiveSrb; // last timer tick active srb 61 ULONG SrbErrorHandlingActive; // error handling of srb is activated 62 ULONG TimerWorkQueueEnabled; // timer work queue enabled 63 ULONG InstanceCount; // pdo instance count 64 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; 65 66 typedef struct 67 { 68 USBSTOR_COMMON_DEVICE_EXTENSION Common; 69 PDEVICE_OBJECT LowerDeviceObject; // points to FDO 70 UCHAR LUN; // lun id 71 PVOID InquiryData; // USB SCSI inquiry data 72 PUCHAR FormatData; // USB SCSI Read Format Capacity Data 73 UCHAR Claimed; // indicating if it has been claimed by upper driver 74 ULONG BlockLength; // length of block 75 ULONG LastLogicBlockAddress; // last block address 76 PDEVICE_OBJECT *PDODeviceObject; // entry in pdo list 77 PDEVICE_OBJECT Self; // self 78 UCHAR MediumTypeCode; // floppy medium type code 79 UCHAR IsFloppy; // is device floppy 80 }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; 81 82 // 83 // max lun command identifier 84 // 85 #define USB_BULK_GET_MAX_LUN 0xFE 86 #define USB_BULK_RESET_DEVICE 0xFF 87 88 #include <pshpack1.h> 89 typedef struct 90 { 91 ULONG Signature; // CBW signature 92 ULONG Tag; // CBW Tag of operation 93 ULONG DataTransferLength; // data transfer length 94 UCHAR Flags; // CBW Flags endpoint direction 95 UCHAR LUN; // lun unit 96 UCHAR CommandBlockLength; // Command block length 97 UCHAR CommandBlock[16]; 98 }CBW, *PCBW; 99 100 C_ASSERT(sizeof(CBW) == 31); 101 102 103 #define CBW_SIGNATURE 0x43425355 104 #define CSW_SIGNATURE 0x53425355 105 106 #define MAX_LUN 0xF 107 108 typedef struct 109 { 110 ULONG Signature; // CSW signature 111 ULONG Tag; // CSW tag 112 ULONG DataResidue; // CSW data transfer diff 113 UCHAR Status; // CSW status 114 }CSW, *PCSW; 115 116 //-------------------------------------------------------------------------------------------------------------------------------------------- 117 // 118 // UFI INQUIRY command 119 // 120 typedef struct 121 { 122 UCHAR Code; // operation code 0x12 123 UCHAR LUN; // lun address 124 UCHAR PageCode; // product data information, always 0x00 125 UCHAR Reserved; // reserved 0x00 126 UCHAR AllocationLength; // length of inquiry data to be returned, default 36 bytes 127 UCHAR Reserved1[7]; //reserved bytes 0x00 128 }UFI_INQUIRY_CMD, *PUFI_INQUIRY_CMD; 129 130 C_ASSERT(sizeof(UFI_INQUIRY_CMD) == 12); 131 132 #define UFI_INQUIRY_CMD_LEN 0x6 133 134 // 135 // UFI INQUIRY command response 136 // 137 typedef struct 138 { 139 UCHAR DeviceType; // device type 140 UCHAR RMB; // removable media bit 141 UCHAR Version; // contains version 0x00 142 UCHAR Format; // response format 143 UCHAR Length; // additional length 144 UCHAR Reserved[3]; // reserved 145 UCHAR Vendor[8]; // vendor identification string 146 UCHAR Product[16]; // product identification string 147 UCHAR Revision[4]; // product revision code 148 }UFI_INQUIRY_RESPONSE, *PUFI_INQUIRY_RESPONSE; 149 150 C_ASSERT(sizeof(UFI_INQUIRY_RESPONSE) == 36); 151 152 //-------------------------------------------------------------------------------------------------------------------------------------------- 153 // 154 // UFI read cmd 155 // 156 typedef struct 157 { 158 UCHAR Code; // operation code 159 UCHAR LUN; // lun 160 UCHAR LogicalBlockByte0; // lba byte 0 161 UCHAR LogicalBlockByte1; // lba byte 1 162 UCHAR LogicalBlockByte2; // lba byte 2 163 UCHAR LogicalBlockByte3; // lba byte 3 164 UCHAR Reserved; // reserved 0x00 165 UCHAR ContiguousLogicBlocksByte0; // msb contiguous logic blocks byte 166 UCHAR ContiguousLogicBlocksByte1; // msb contiguous logic blocks 167 UCHAR Reserved1[3]; // reserved 0x00 168 }UFI_READ_WRITE_CMD; 169 170 C_ASSERT(sizeof(UFI_READ_WRITE_CMD) == 12); 171 172 #define UFI_READ_WRITE_CMD_LEN (0xA) 173 174 //-------------------------------------------------------------------------------------------------------------------------------------------- 175 // 176 // UFI read capacity cmd 177 // 178 typedef struct 179 { 180 UCHAR Code; // operation code 0x25 181 UCHAR LUN; // lun address 182 UCHAR LBA[4]; // logical block address, should be zero 183 UCHAR Reserved1[2]; // reserved 0x00 184 UCHAR PMI; // PMI = 0x00 185 UCHAR Reserved2[3]; // reserved 0x00 186 }UFI_CAPACITY_CMD, *PUFI_CAPACITY_CMD; 187 188 C_ASSERT(sizeof(UFI_CAPACITY_CMD) == 12); 189 190 #define UFI_CAPACITY_CMD_LEN 0xA //FIXME support length 16 too if requested 191 192 // 193 // UFI Read Capacity command response 194 // 195 typedef struct 196 { 197 ULONG LastLogicalBlockAddress; // last logical block address 198 ULONG BlockLength; // block length in bytes 199 }UFI_CAPACITY_RESPONSE, *PUFI_CAPACITY_RESPONSE; 200 201 #define UFI_READ_CAPACITY_CMD_LEN 0xA 202 C_ASSERT(sizeof(UFI_CAPACITY_RESPONSE) == 8); 203 204 //-------------------------------------------------------------------------------------------------------------------------------------------- 205 // 206 // UFI sense mode cmd 207 // 208 typedef struct 209 { 210 UCHAR Code; // operation code 211 UCHAR LUN; // lun address 212 UCHAR PageCode:6; // page code selector 213 UCHAR PC:2; // type of parameters to be returned 214 UCHAR Reserved[4]; // reserved 0x00 215 USHORT AllocationLength; // parameters length 216 UCHAR Reserved1[3]; 217 }UFI_SENSE_CMD, *PUFI_SENSE_CMD; 218 219 C_ASSERT(sizeof(UFI_SENSE_CMD) == 12); 220 221 #define UFI_SENSE_CMD_LEN (6) 222 223 typedef struct 224 { 225 USHORT ModeDataLength; // length of parameters for sense cmd 226 UCHAR MediumTypeCode; // 00 for mass storage, 0x94 for floppy 227 UCHAR WP:1; // write protect bit 228 UCHAR Reserved1:2; // reserved 00 229 UCHAR DPOFUA:1; // should be zero 230 UCHAR Reserved2:4; // reserved 231 UCHAR Reserved[4]; // reserved 232 }UFI_MODE_PARAMETER_HEADER, *PUFI_MODE_PARAMETER_HEADER; 233 234 235 C_ASSERT(sizeof(UFI_MODE_PARAMETER_HEADER) == 8); 236 237 typedef struct 238 { 239 UCHAR PC; 240 UCHAR PageLength; 241 UCHAR Reserved1; 242 UCHAR ITM; 243 UCHAR Flags; 244 UCHAR Reserved[3]; 245 }UFI_TIMER_PROTECT_PAGE, *PUFI_TIMER_PROTECT_PAGE; 246 C_ASSERT(sizeof(UFI_TIMER_PROTECT_PAGE) == 8); 247 248 //-------------------------------------------------------------------------------------------------------------------------------------------- 249 // 250 // UFI read capacity cmd 251 // 252 253 typedef struct 254 { 255 UCHAR Code; 256 UCHAR LUN; 257 UCHAR Reserved[5]; 258 UCHAR AllocationLengthMsb; 259 UCHAR AllocationLengthLsb; 260 UCHAR Reserved1[3]; 261 }UFI_READ_FORMAT_CAPACITY, *PUFI_READ_FORMAT_CAPACITY; 262 263 C_ASSERT(sizeof(UFI_READ_FORMAT_CAPACITY) == 12); 264 265 #define UFI_READ_FORMAT_CAPACITY_CMD_LEN (10) 266 267 typedef struct 268 { 269 UCHAR Reserved1; 270 UCHAR Reserved2; 271 UCHAR Reserved3; 272 UCHAR CapacityLength; 273 }UFI_CAPACITY_FORMAT_HEADER, *PUFI_CAPACITY_FORMAT_HEADER; 274 275 C_ASSERT(sizeof(UFI_CAPACITY_FORMAT_HEADER) == 4); 276 277 typedef struct 278 { 279 ULONG BlockCount; 280 UCHAR Code; 281 UCHAR BlockLengthByte0; 282 UCHAR BlockLengthByte1; 283 UCHAR BlockLengthByte2; 284 }UFI_CAPACITY_DESCRIPTOR, *PUFI_CAPACITY_DESCRIPTOR; 285 286 #define UNFORMATTED_MEDIA_CODE_DESCRIPTORY_TYPE (1) 287 #define FORMAT_MEDIA_CODE_DESCRIPTOR_TYPE (2) 288 #define CARTRIDGE_MEDIA_CODE_DESCRIPTOR_TYPE (3) 289 290 291 292 293 //-------------------------------------------------------------------------------------------------------------------------------------------- 294 // 295 // UFI test unit command 296 // 297 298 typedef struct 299 { 300 UCHAR Code; // operation code 0x00 301 UCHAR LUN; // lun 302 UCHAR Reserved[10]; // reserved 0x00 303 }UFI_TEST_UNIT_CMD, *PUFI_TEST_UNIT_CMD; 304 305 C_ASSERT(sizeof(UFI_TEST_UNIT_CMD) == 12); 306 307 #define UFI_TEST_UNIT_CMD_LEN (6) 308 309 //------------------------------------------------------------------------------------------------------------------------------------------- 310 typedef struct 311 { 312 UCHAR Bytes[16]; 313 }UFI_UNKNOWN_CMD, *PUFI_UNKNOWN_CMD; 314 315 #include <poppack.h> 316 317 typedef struct 318 { 319 union 320 { 321 PCBW cbw; 322 PCSW csw; 323 }; 324 URB Urb; 325 PIRP Irp; 326 ULONG TransferDataLength; 327 PUCHAR TransferData; 328 PFDO_DEVICE_EXTENSION FDODeviceExtension; 329 PPDO_DEVICE_EXTENSION PDODeviceExtension; 330 PMDL TransferBufferMDL; 331 ULONG ErrorIndex; 332 ULONG RetryCount; 333 }IRP_CONTEXT, *PIRP_CONTEXT; 334 335 typedef struct _ERRORHANDLER_WORKITEM_DATA 336 { 337 PDEVICE_OBJECT DeviceObject; 338 PIRP_CONTEXT Context; 339 WORK_QUEUE_ITEM WorkQueueItem; 340 PIRP Irp; 341 } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA; 342 343 344 //--------------------------------------------------------------------- 345 // 346 // fdo.c routines 347 // 348 NTSTATUS 349 USBSTOR_FdoHandlePnp( 350 IN PDEVICE_OBJECT DeviceObject, 351 IN OUT PIRP Irp); 352 353 //--------------------------------------------------------------------- 354 // 355 // pdo.c routines 356 // 357 NTSTATUS 358 USBSTOR_PdoHandlePnp( 359 IN PDEVICE_OBJECT DeviceObject, 360 IN OUT PIRP Irp); 361 362 NTSTATUS 363 USBSTOR_CreatePDO( 364 IN PDEVICE_OBJECT DeviceObject, 365 IN UCHAR LUN); 366 367 //--------------------------------------------------------------------- 368 // 369 // misc.c routines 370 // 371 NTSTATUS 372 NTAPI 373 USBSTOR_SyncForwardIrp( 374 IN PDEVICE_OBJECT DeviceObject, 375 IN OUT PIRP Irp); 376 377 NTSTATUS 378 NTAPI 379 USBSTOR_GetBusInterface( 380 IN PDEVICE_OBJECT DeviceObject, 381 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface); 382 383 PVOID 384 AllocateItem( 385 IN POOL_TYPE PoolType, 386 IN ULONG ItemSize); 387 388 VOID 389 FreeItem( 390 IN PVOID Item); 391 392 NTSTATUS 393 USBSTOR_SyncUrbRequest( 394 IN PDEVICE_OBJECT DeviceObject, 395 OUT PURB UrbRequest); 396 397 NTSTATUS 398 USBSTOR_GetMaxLUN( 399 IN PDEVICE_OBJECT DeviceObject, 400 IN PFDO_DEVICE_EXTENSION DeviceExtension); 401 402 NTSTATUS 403 NTAPI 404 USBSTOR_SyncForwardIrpCompletionRoutine( 405 PDEVICE_OBJECT DeviceObject, 406 PIRP Irp, 407 PVOID Context); 408 409 NTSTATUS 410 USBSTOR_ResetDevice( 411 IN PDEVICE_OBJECT DeviceObject, 412 IN PFDO_DEVICE_EXTENSION DeviceExtension); 413 414 BOOLEAN 415 USBSTOR_IsFloppy( 416 IN PUCHAR Buffer, 417 IN ULONG BufferLength, 418 OUT PUCHAR MediumTypeCode); 419 420 //--------------------------------------------------------------------- 421 // 422 // descriptor.c routines 423 // 424 425 NTSTATUS 426 USBSTOR_GetDescriptors( 427 IN PDEVICE_OBJECT DeviceObject); 428 429 NTSTATUS 430 USBSTOR_SelectConfigurationAndInterface( 431 IN PDEVICE_OBJECT DeviceObject, 432 IN PFDO_DEVICE_EXTENSION DeviceExtension); 433 434 NTSTATUS 435 USBSTOR_GetPipeHandles( 436 IN PFDO_DEVICE_EXTENSION DeviceExtension); 437 438 //--------------------------------------------------------------------- 439 // 440 // scsi.c routines 441 // 442 NTSTATUS 443 USBSTOR_HandleExecuteSCSI( 444 IN PDEVICE_OBJECT DeviceObject, 445 IN PIRP Irp, 446 IN ULONG RetryCount); 447 448 NTSTATUS 449 NTAPI 450 USBSTOR_CSWCompletionRoutine( 451 PDEVICE_OBJECT DeviceObject, 452 PIRP Irp, 453 PVOID Ctx); 454 455 NTSTATUS 456 USBSTOR_SendCBW( 457 PIRP_CONTEXT Context, 458 PIRP Irp); 459 460 VOID 461 USBSTOR_SendCSW( 462 PIRP_CONTEXT Context, 463 PIRP Irp); 464 465 466 //--------------------------------------------------------------------- 467 // 468 // disk.c routines 469 // 470 NTSTATUS 471 USBSTOR_HandleInternalDeviceControl( 472 IN PDEVICE_OBJECT DeviceObject, 473 IN PIRP Irp); 474 475 NTSTATUS 476 USBSTOR_HandleDeviceControl( 477 IN PDEVICE_OBJECT DeviceObject, 478 IN PIRP Irp); 479 480 //--------------------------------------------------------------------- 481 // 482 // queue.c routines 483 // 484 VOID 485 NTAPI 486 USBSTOR_StartIo( 487 PDEVICE_OBJECT DeviceObject, 488 PIRP Irp); 489 490 VOID 491 USBSTOR_QueueWaitForPendingRequests( 492 IN PDEVICE_OBJECT DeviceObject); 493 494 VOID 495 USBSTOR_QueueRelease( 496 IN PDEVICE_OBJECT DeviceObject); 497 498 BOOLEAN 499 USBSTOR_QueueAddIrp( 500 IN PDEVICE_OBJECT DeviceObject, 501 IN PIRP Irp); 502 503 VOID 504 NTAPI 505 USBSTOR_CancelIo( 506 IN PDEVICE_OBJECT DeviceObject, 507 IN PIRP Irp); 508 509 VOID 510 USBSTOR_QueueInitialize( 511 PFDO_DEVICE_EXTENSION FDODeviceExtension); 512 513 VOID 514 NTAPI 515 ErrorHandlerWorkItemRoutine( 516 PVOID Context); 517 518 VOID 519 NTAPI 520 ResetHandlerWorkItemRoutine( 521 PVOID Context); 522 523 524 525 VOID 526 USBSTOR_QueueNextRequest( 527 IN PDEVICE_OBJECT DeviceObject); 528 529 VOID 530 USBSTOR_QueueTerminateRequest( 531 IN PDEVICE_OBJECT DeviceObject, 532 IN PIRP Irp); 533 534 /* error.c */ 535 NTSTATUS 536 USBSTOR_GetEndpointStatus( 537 IN PDEVICE_OBJECT DeviceObject, 538 IN UCHAR bEndpointAddress, 539 OUT PUSHORT Value); 540 541 NTSTATUS 542 USBSTOR_ResetPipeWithHandle( 543 IN PDEVICE_OBJECT DeviceObject, 544 IN USBD_PIPE_HANDLE PipeHandle); 545 546 VOID 547 NTAPI 548 USBSTOR_TimerRoutine( 549 PDEVICE_OBJECT DeviceObject, 550 PVOID Context); 551 552 #endif /* _USBSTOR_H_ */ 553