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