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 typedef struct 316 { 317 union 318 { 319 PCBW cbw; 320 PCSW csw; 321 }; 322 URB Urb; 323 PIRP Irp; 324 ULONG TransferDataLength; 325 PUCHAR TransferData; 326 PFDO_DEVICE_EXTENSION FDODeviceExtension; 327 PPDO_DEVICE_EXTENSION PDODeviceExtension; 328 PMDL TransferBufferMDL; 329 ULONG ErrorIndex; 330 ULONG RetryCount; 331 }IRP_CONTEXT, *PIRP_CONTEXT; 332 333 typedef struct _ERRORHANDLER_WORKITEM_DATA 334 { 335 PDEVICE_OBJECT DeviceObject; 336 PIRP_CONTEXT Context; 337 WORK_QUEUE_ITEM WorkQueueItem; 338 PIRP Irp; 339 } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA; 340 341 342 //--------------------------------------------------------------------- 343 // 344 // fdo.c routines 345 // 346 NTSTATUS 347 USBSTOR_FdoHandlePnp( 348 IN PDEVICE_OBJECT DeviceObject, 349 IN OUT PIRP Irp); 350 351 //--------------------------------------------------------------------- 352 // 353 // pdo.c routines 354 // 355 NTSTATUS 356 USBSTOR_PdoHandlePnp( 357 IN PDEVICE_OBJECT DeviceObject, 358 IN OUT PIRP Irp); 359 360 NTSTATUS 361 USBSTOR_CreatePDO( 362 IN PDEVICE_OBJECT DeviceObject, 363 IN UCHAR LUN); 364 365 //--------------------------------------------------------------------- 366 // 367 // misc.c routines 368 // 369 NTSTATUS 370 NTAPI 371 USBSTOR_SyncForwardIrp( 372 IN PDEVICE_OBJECT DeviceObject, 373 IN OUT PIRP Irp); 374 375 NTSTATUS 376 NTAPI 377 USBSTOR_GetBusInterface( 378 IN PDEVICE_OBJECT DeviceObject, 379 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface); 380 381 PVOID 382 AllocateItem( 383 IN POOL_TYPE PoolType, 384 IN ULONG ItemSize); 385 386 VOID 387 FreeItem( 388 IN PVOID Item); 389 390 NTSTATUS 391 USBSTOR_SyncUrbRequest( 392 IN PDEVICE_OBJECT DeviceObject, 393 OUT PURB UrbRequest); 394 395 NTSTATUS 396 USBSTOR_GetMaxLUN( 397 IN PDEVICE_OBJECT DeviceObject, 398 IN PFDO_DEVICE_EXTENSION DeviceExtension); 399 400 NTSTATUS 401 NTAPI 402 USBSTOR_SyncForwardIrpCompletionRoutine( 403 PDEVICE_OBJECT DeviceObject, 404 PIRP Irp, 405 PVOID Context); 406 407 NTSTATUS 408 USBSTOR_ResetDevice( 409 IN PDEVICE_OBJECT DeviceObject, 410 IN PFDO_DEVICE_EXTENSION DeviceExtension); 411 412 BOOLEAN 413 USBSTOR_IsFloppy( 414 IN PUCHAR Buffer, 415 IN ULONG BufferLength, 416 OUT PUCHAR MediumTypeCode); 417 418 //--------------------------------------------------------------------- 419 // 420 // descriptor.c routines 421 // 422 423 NTSTATUS 424 USBSTOR_GetDescriptors( 425 IN PDEVICE_OBJECT DeviceObject); 426 427 NTSTATUS 428 USBSTOR_SelectConfigurationAndInterface( 429 IN PDEVICE_OBJECT DeviceObject, 430 IN PFDO_DEVICE_EXTENSION DeviceExtension); 431 432 NTSTATUS 433 USBSTOR_GetPipeHandles( 434 IN PFDO_DEVICE_EXTENSION DeviceExtension); 435 436 //--------------------------------------------------------------------- 437 // 438 // scsi.c routines 439 // 440 NTSTATUS 441 USBSTOR_HandleExecuteSCSI( 442 IN PDEVICE_OBJECT DeviceObject, 443 IN PIRP Irp, 444 IN ULONG RetryCount); 445 446 NTSTATUS 447 NTAPI 448 USBSTOR_CSWCompletionRoutine( 449 PDEVICE_OBJECT DeviceObject, 450 PIRP Irp, 451 PVOID Ctx); 452 453 NTSTATUS 454 USBSTOR_SendCBW( 455 PIRP_CONTEXT Context, 456 PIRP Irp); 457 458 VOID 459 USBSTOR_SendCSW( 460 PIRP_CONTEXT Context, 461 PIRP Irp); 462 463 464 //--------------------------------------------------------------------- 465 // 466 // disk.c routines 467 // 468 NTSTATUS 469 USBSTOR_HandleInternalDeviceControl( 470 IN PDEVICE_OBJECT DeviceObject, 471 IN PIRP Irp); 472 473 NTSTATUS 474 USBSTOR_HandleDeviceControl( 475 IN PDEVICE_OBJECT DeviceObject, 476 IN PIRP Irp); 477 478 //--------------------------------------------------------------------- 479 // 480 // queue.c routines 481 // 482 VOID 483 NTAPI 484 USBSTOR_StartIo( 485 PDEVICE_OBJECT DeviceObject, 486 PIRP Irp); 487 488 VOID 489 USBSTOR_QueueWaitForPendingRequests( 490 IN PDEVICE_OBJECT DeviceObject); 491 492 VOID 493 USBSTOR_QueueRelease( 494 IN PDEVICE_OBJECT DeviceObject); 495 496 BOOLEAN 497 USBSTOR_QueueAddIrp( 498 IN PDEVICE_OBJECT DeviceObject, 499 IN PIRP Irp); 500 501 VOID 502 NTAPI 503 USBSTOR_CancelIo( 504 IN PDEVICE_OBJECT DeviceObject, 505 IN PIRP Irp); 506 507 VOID 508 USBSTOR_QueueInitialize( 509 PFDO_DEVICE_EXTENSION FDODeviceExtension); 510 511 VOID 512 NTAPI 513 ErrorHandlerWorkItemRoutine( 514 PVOID Context); 515 516 VOID 517 NTAPI 518 ResetHandlerWorkItemRoutine( 519 PVOID Context); 520 521 522 523 VOID 524 USBSTOR_QueueNextRequest( 525 IN PDEVICE_OBJECT DeviceObject); 526 527 VOID 528 USBSTOR_QueueTerminateRequest( 529 IN PDEVICE_OBJECT DeviceObject, 530 IN PIRP Irp); 531 532 /* error.c */ 533 NTSTATUS 534 USBSTOR_GetEndpointStatus( 535 IN PDEVICE_OBJECT DeviceObject, 536 IN UCHAR bEndpointAddress, 537 OUT PUSHORT Value); 538 539 NTSTATUS 540 USBSTOR_ResetPipeWithHandle( 541 IN PDEVICE_OBJECT DeviceObject, 542 IN USBD_PIPE_HANDLE PipeHandle); 543 544 VOID 545 NTAPI 546 USBSTOR_TimerRoutine( 547 PDEVICE_OBJECT DeviceObject, 548 PVOID Context); 549 550 #endif /* _USBSTOR_H_ */ 551