2 * umss.c - USB driver stack project for Windows NT 4.0
4 * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program/include file is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * this program (in the main directory of the distribution, the file
18 * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "usbdriver.h"
28 #define UMSS_EXIT_DISPATCH( dev_OBJ, staTUS, iRp ) \
30 iRp->IoStatus.Status = staTUS;\
31 if( staTUS != STATUS_PENDING)\
33 IoCompleteRequest( iRp, IO_NO_INCREMENT);\
36 IoMarkIrpPending( iRp );\
37 IoStartPacket( dev_OBJ, iRp, NULL, NULL ); \
38 return STATUS_PENDING;\
41 #define UMSS_COMPLETE_START_IO( dev_OBJ, staTUS, iRP ) \
43 iRP->IoStatus.Status = staTUS;\
44 if( staTUS != STATUS_PENDING )\
46 IoStartNextPacket( dev_OBJ, FALSE );\
47 IoCompleteRequest( iRP, IO_NO_INCREMENT );\
52 extern VOID
gendrv_startio(IN PDEVICE_OBJECT dev_obj
, IN PIRP irp
);
54 NTSYSAPI NTSTATUS NTAPI
ZwLoadDriver(IN PUNICODE_STRING DriverServiceName
);
59 ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes
,
60 IN POBJECT_TYPE ObjectType OPTIONAL
,
61 IN KPROCESSOR_MODE AccessMode
,
62 IN OUT PACCESS_STATE AccessState OPTIONAL
,
63 IN ACCESS_MASK DesiredAccess OPTIONAL
,
64 IN OUT PVOID ParseContext OPTIONAL
, OUT PHANDLE Handle
);
66 VOID NTAPI
umss_start_io(IN PDEVICE_OBJECT dev_obj
, IN PIRP irp
);
67 NTSTATUS
umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj
, PIRP irp
);
68 BOOLEAN
umss_connect(PDEV_CONNECT_DATA dev_mgr
, DEV_HANDLE dev_handle
);
69 BOOLEAN
umss_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
70 BOOLEAN
umss_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
71 NTSTATUS
umss_dispatch_routine(PDEVICE_OBJECT pdev_obj
, PIRP irp
);
72 VOID
umss_set_cfg_completion(PURB purb
, PVOID pcontext
);
73 VOID NTAPI
umss_start_create_device(IN PVOID Parameter
);
74 BOOLEAN
umss_delete_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdrvr
, PDEVICE_OBJECT dev_obj
, BOOLEAN is_if
);
75 BOOLEAN
umss_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
);
76 NTSTATUS
umss_process_srb(PDEVICE_OBJECT dev_obj
, PIRP irp
);
77 VOID
umss_load_class_driver(PVOID context
);
78 BOOLEAN
umss_tsc_to_sff(PIO_PACKET io_packet
);
79 VOID
umss_fix_sff_result(PIO_PACKET io_packet
, SCSI_REQUEST_BLOCK
* srb
);
82 umss_create_port_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
85 // currently a port device is a connection point
86 // and upper driver use this to register itself
87 // with umss driver for future notification of
88 // pnp event. 2004-03-22 23:12:41
93 UNICODE_STRING name_string
, symb_link
;
94 PUMSS_PORT_DEV_EXT pdev_ext
;
96 sprintf(dev_name
, "\\Device\\usbPort_%d", (int)0);
98 RtlInitString(&string
, dev_name
);
99 RtlAnsiStringToUnicodeString(&name_string
, &string
, TRUE
);
102 status
= IoCreateDevice(dev_mgr
->usb_driver_obj
,
103 sizeof(UMSS_PORT_DEV_EXT
), &name_string
, FILE_USB_DEV_TYPE
, 0, TRUE
, &pdev
);
105 if (status
== STATUS_SUCCESS
)
110 pdev
->Flags
|= DO_BUFFERED_IO
;
112 pdev
->Flags
&= ~DO_DEVICE_INITIALIZING
;
113 pdev
->StackSize
= 2; //one for fdo, one for file device obj
115 pdev_ext
= (PUMSS_PORT_DEV_EXT
) pdev
->DeviceExtension
;
117 pdev_ext
->dev_ext_hdr
.type
= NTDEV_TYPE_CLIENT_DEV
;
118 pdev_ext
->dev_ext_hdr
.dispatch
= umss_port_dispatch_routine
;
119 pdev_ext
->dev_ext_hdr
.start_io
= NULL
;
120 pdev_ext
->dev_ext_hdr
.dev_mgr
= dev_mgr
;
121 pdev_ext
->pdriver
= pdriver
;
123 sprintf(dev_name
, "\\DosDevices\\usbPort%d", (int)0);
125 RtlInitString(&string
, dev_name
);
126 RtlAnsiStringToUnicodeString(&symb_link
, &string
, TRUE
);
127 IoCreateSymbolicLink(&symb_link
, &name_string
);
128 RtlFreeUnicodeString(&symb_link
);
132 RtlFreeUnicodeString(&name_string
);
137 umss_delete_port_device(PDEVICE_OBJECT dev_obj
)
141 UNICODE_STRING symb_link
;
146 // remove the symbolic link
147 sprintf(dev_name
, "\\DosDevices\\usbPort%d", (int)0);
148 RtlInitString(&string
, dev_name
);
149 RtlAnsiStringToUnicodeString(&symb_link
, &string
, TRUE
);
150 IoDeleteSymbolicLink(&symb_link
);
151 RtlFreeUnicodeString(&symb_link
);
153 if (dev_obj
->ReferenceCount
== 0)
155 IoDeleteDevice(dev_obj
);
156 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_delete_port_device(): port device object is removed\n"));
161 // FIXME!!! there can not be sent IOCTL_SUBMIT_URB_XXX while
162 // the IOCTL_SUBMIT_CDB_XXX are active. may confuse the device.
164 // 2004-03-22 23:12:26
166 umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj
, PIRP irp
)
170 PIO_STACK_LOCATION irp_stack
;
171 PUMSS_PORT_DEV_EXT pdev_ext
;
172 PUMSS_DRVR_EXTENSION pdrvr_ext
;
174 if (pdev_obj
== NULL
|| irp
== NULL
)
175 return STATUS_INVALID_PARAMETER
;
177 status
= STATUS_SUCCESS
;
178 irp_stack
= IoGetCurrentIrpStackLocation(irp
);
179 ctrl_code
= irp_stack
->Parameters
.DeviceIoControl
.IoControlCode
;
181 pdev_ext
= (PUMSS_PORT_DEV_EXT
) pdev_obj
->DeviceExtension
;
183 switch (irp_stack
->MajorFunction
)
185 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
189 case IOCTL_REGISTER_DRIVER
:
191 PCLASS_DRV_REG_INFO pcdri
;
192 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(CLASS_DRV_REG_INFO
))
194 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
197 pcdri
= irp
->AssociatedIrp
.SystemBuffer
;
198 if (pcdri
->fdo_driver
== NULL
|| pcdri
->add_device
== NULL
|| pcdri
->pnp_dispatch
== NULL
)
200 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
202 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdev_ext
->pdriver
->driver_ext
;
203 pdrvr_ext
->class_driver_info
.fdo_driver
= pcdri
->fdo_driver
;
204 pdrvr_ext
->class_driver_info
.add_device
= pcdri
->add_device
;
205 pdrvr_ext
->class_driver_info
.pnp_dispatch
= pcdri
->pnp_dispatch
;
206 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
208 case IOCTL_REVOKE_DRIVER
:
210 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdev_ext
->pdriver
->driver_ext
;
211 pdrvr_ext
->class_driver_info
.fdo_driver
= NULL
;
212 pdrvr_ext
->class_driver_info
.add_device
= NULL
;
213 pdrvr_ext
->class_driver_info
.pnp_dispatch
= NULL
;
214 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
221 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
224 EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST
, irp
);
228 umss_driver_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
230 PUMSS_DRVR_EXTENSION pdrvr_ext
;
232 if (dev_mgr
== NULL
|| pdriver
== NULL
)
235 //init driver structure, no PNP table functions
236 pdriver
->driver_desc
.flags
= USB_DRIVER_FLAG_DEV_CAPABLE
;
237 pdriver
->driver_desc
.vendor_id
= 0x0dd8; // USB Vendor ID
238 pdriver
->driver_desc
.product_id
= 0x0003; // USB Product ID.
239 pdriver
->driver_desc
.release_num
= 0x100; // Release Number of Device
241 pdriver
->driver_desc
.config_val
= 1; // Configuration Value
242 pdriver
->driver_desc
.if_num
= 1; // Interface Number
243 pdriver
->driver_desc
.if_class
= USB_CLASS_MASS_STORAGE
; // Interface Class
244 pdriver
->driver_desc
.if_sub_class
= 0; // Interface SubClass
245 pdriver
->driver_desc
.if_protocol
= 0; // Interface Protocol
247 pdriver
->driver_desc
.driver_name
= "USB Mass Storage driver"; // Driver name for Name Registry
248 pdriver
->driver_desc
.dev_class
= USB_CLASS_MASS_STORAGE
;
249 pdriver
->driver_desc
.dev_sub_class
= 0; // Device Subclass
250 pdriver
->driver_desc
.dev_protocol
= 0; // Protocol Info.
252 pdriver
->driver_ext
= usb_alloc_mem(NonPagedPool
, sizeof(UMSS_DRVR_EXTENSION
));
253 if (!pdriver
->driver_ext
) return FALSE
;
254 pdriver
->driver_ext_size
= sizeof(UMSS_DRVR_EXTENSION
);
256 RtlZeroMemory(pdriver
->driver_ext
, sizeof(UMSS_DRVR_EXTENSION
));
257 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdriver
->driver_ext
;
258 pdrvr_ext
->dev_count
= 0;
259 InitializeListHead(&pdrvr_ext
->dev_list
);
260 ExInitializeFastMutex(&pdrvr_ext
->dev_list_mutex
);
262 pdriver
->disp_tbl
.version
= 1;
263 pdriver
->disp_tbl
.dev_connect
= umss_connect
;
264 pdriver
->disp_tbl
.dev_disconnect
= umss_disconnect
;
265 pdriver
->disp_tbl
.dev_stop
= umss_stop
;
266 pdriver
->disp_tbl
.dev_reserved
= NULL
;
268 if ((pdrvr_ext
->port_dev_obj
= umss_create_port_device(dev_mgr
, pdriver
)) == NULL
)
270 usb_free_mem(pdriver
->driver_ext
);
271 pdriver
->driver_ext
= NULL
;
272 pdriver
->driver_ext_size
= 0;
273 pdriver
->disp_tbl
.dev_connect
= NULL
;
274 pdriver
->disp_tbl
.dev_stop
= NULL
;
275 pdriver
->disp_tbl
.dev_disconnect
= NULL
;
279 umss_load_class_driver(NULL
);
281 // umss_schedule_workitem( NULL, umss_load_class_driver, NULL, 0 );
282 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_driver_init(): umss driver is initialized\n"));
287 umss_driver_destroy(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
289 PUMSS_DRVR_EXTENSION pdrvr_ext
;
290 if (dev_mgr
== NULL
|| pdriver
== NULL
)
293 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdriver
->driver_ext
;
294 umss_delete_port_device(pdrvr_ext
->port_dev_obj
);
295 pdrvr_ext
->port_dev_obj
= NULL
;
297 ASSERT(IsListEmpty(&pdrvr_ext
->dev_list
) == TRUE
);
298 usb_free_mem(pdriver
->driver_ext
);
299 pdriver
->driver_ext
= NULL
;
300 pdriver
->driver_ext_size
= 0;
301 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_driver_destroy(): umss driver is destroyed\n"));
306 umss_create_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER umss_drvr
, DEV_HANDLE dev_handle
, BOOLEAN is_if
)
309 CHAR dev_name
[64], dev_id
;
313 UNICODE_STRING name_string
, symb_link
;
314 PUMSS_DRVR_EXTENSION pdrvr_ext
;
315 PUMSS_DEVICE_EXTENSION pdev_ext
;
317 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_create_device(): entering...\n"));
318 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) umss_drvr
->driver_ext
;
319 dev_id
= (UCHAR
) dev_id_from_handle(dev_handle
); // pdrvr_ext->dev_count;
322 sprintf(dev_name
, "\\Device\\umssdev_%d", (int)dev_id
);
324 sprintf(dev_name
, "\\Device\\umssifdev_%d", (int)dev_id
);
326 RtlInitString(&string
, dev_name
);
327 RtlAnsiStringToUnicodeString(&name_string
, &string
, TRUE
);
330 status
= IoCreateDevice(dev_mgr
->usb_driver_obj
,
331 sizeof(UMSS_DEVICE_EXTENSION
),
338 if (status
== STATUS_SUCCESS
)
343 pdev
->Flags
|= DO_DIRECT_IO
;
345 pdev
->Flags
&= ~DO_DEVICE_INITIALIZING
;
346 pdev
->StackSize
= 2; //one for fdo, one for file device obj
348 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) pdev
->DeviceExtension
;
350 //may be accessed by other thread
351 ExAcquireFastMutex(&pdrvr_ext
->dev_list_mutex
);
352 InsertTailList(&pdrvr_ext
->dev_list
, &pdev_ext
->dev_obj_link
);
353 pdrvr_ext
->dev_count
++;
354 ExReleaseFastMutex(&pdrvr_ext
->dev_list_mutex
);
357 pdev_ext
->flags
|= UMSS_DEV_FLAG_IF_DEV
;
359 pdev_ext
->umss_dev_id
= dev_id
;
360 pdev_ext
->pdo
= pdev
;
361 pdev_ext
->dev_handle
= dev_handle
;
362 pdev_ext
->dev_mgr
= dev_mgr
;
363 pdev_ext
->pdriver
= umss_drvr
;
365 pdev_ext
->dev_ext_hdr
.type
= NTDEV_TYPE_CLIENT_DEV
;
366 pdev_ext
->dev_ext_hdr
.dispatch
= umss_dispatch_routine
;
367 pdev_ext
->dev_ext_hdr
.start_io
= umss_start_io
;
368 pdev_ext
->dev_ext_hdr
.dev_mgr
= dev_mgr
;
371 sprintf(dev_name
, "\\DosDevices\\umssdev%d", (int)dev_id
);
373 sprintf(dev_name
, "\\DosDevices\\umssifdev%d", (int)dev_id
);
375 RtlInitString(&string
, dev_name
);
376 RtlAnsiStringToUnicodeString(&symb_link
, &string
, TRUE
);
377 IoCreateSymbolicLink(&symb_link
, &name_string
);
378 RtlFreeUnicodeString(&symb_link
);
379 KeInitializeEvent(&pdev_ext
->sync_event
, SynchronizationEvent
, FALSE
);
380 KeInitializeSpinLock(&pdev_ext
->dev_lock
);
383 RtlFreeUnicodeString(&name_string
);
388 umss_connect(PDEV_CONNECT_DATA param
, DEV_HANDLE dev_handle
)
392 PUSB_CTRL_SETUP_PACKET psetup
;
393 PUSB_DEV_MANAGER dev_mgr
;
396 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_connect(): entering...\n"));
398 dev_mgr
= param
->dev_mgr
;
399 pdrvr
= param
->pdriver
;
401 //directly set the configuration
402 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
406 psetup
= (PUSB_CTRL_SETUP_PACKET
) (purb
)->setup_packet
;
409 purb
->endp_handle
= dev_handle
| 0xffff;
410 purb
->data_buffer
= NULL
;
411 purb
->data_length
= 0;
412 purb
->completion
= umss_set_cfg_completion
;
413 purb
->context
= dev_mgr
;
414 purb
->reference
= (LONG
) pdrvr
;
415 psetup
->bmRequestType
= 0;
416 psetup
->bRequest
= USB_REQ_SET_CONFIGURATION
;
421 status
= usb_submit_urb(dev_mgr
, purb
);
422 if (status
!= STATUS_PENDING
)
431 umss_set_cfg_completion(PURB purb
, PVOID pcontext
)
433 PUSB_CTRL_SETUP_PACKET psetup
;
435 PWORK_QUEUE_ITEM pwork_item
;
436 PUMSS_CREATE_DATA pcd
;
437 DEV_HANDLE dev_handle
;
439 PUSB_DEV_MANAGER dev_mgr
;
442 if (purb
== NULL
|| pcontext
== NULL
)
445 dev_mgr
= (PUSB_DEV_MANAGER
) pcontext
;
446 pdrvr
= (PUSB_DRIVER
) purb
->reference
;
447 dev_handle
= purb
->endp_handle
& ~0xffff;
450 if (purb
->status
!= STATUS_SUCCESS
)
456 buf
= usb_alloc_mem(NonPagedPool
, 512);
463 //now let's get the descs, one configuration, one interface and two endpoint
464 psetup
= (PUSB_CTRL_SETUP_PACKET
) (purb
)->setup_packet
;
465 purb
->data_buffer
= buf
;
466 purb
->data_length
= 512;
467 purb
->completion
= NULL
; //this is an immediate request, no needs completion
468 purb
->context
= dev_mgr
;
470 psetup
->bmRequestType
= 0x80;
471 psetup
->bRequest
= USB_REQ_GET_DESCRIPTOR
;
472 psetup
->wValue
= USB_DT_CONFIG
<< 8;
474 psetup
->wLength
= 512;
476 status
= usb_submit_urb(dev_mgr
, purb
);
477 if (status
== STATUS_PENDING
)
484 if (status
!= STATUS_SUCCESS
)
491 pcd
= usb_alloc_mem(NonPagedPool
, sizeof(WORK_QUEUE_ITEM
) + sizeof(UMSS_CREATE_DATA
));
500 pcd
->dev_handle
= dev_handle
;
501 pcd
->dev_mgr
= dev_mgr
;
502 pcd
->pdriver
= pdrvr
;
503 pwork_item
= (PWORK_QUEUE_ITEM
) (&pcd
[1]);
505 ExInitializeWorkItem(pwork_item
, umss_start_create_device
, (PVOID
) pcd
);
506 ExQueueWorkItem(pwork_item
, DelayedWorkQueue
);
510 umss_start_create_device(IN PVOID Parameter
)
516 DEV_HANDLE dev_handle
;
518 PDEVICE_OBJECT pdev_obj
;
519 PUSB_DEV_MANAGER dev_mgr
;
520 PUMSS_CREATE_DATA pcd
;
521 PUSB_INTERFACE_DESC pif_desc
;
522 PUSB_ENDPOINT_DESC pendp_desc
;
523 PUMSS_DEVICE_EXTENSION pdev_ext
;
524 PUSB_CONFIGURATION_DESC pconfig_desc
;
526 USE_BASIC_NON_PENDING_IRQL
;
528 if (Parameter
== NULL
)
531 pcd
= (PUMSS_CREATE_DATA
) Parameter
;
532 desc_buf
= pcd
->desc_buf
;
533 dev_mgr
= pcd
->dev_mgr
;
534 dev_handle
= pcd
->dev_handle
;
535 pdrvr
= pcd
->pdriver
;
539 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
540 if (status
!= STATUS_SUCCESS
)
542 usb_free_mem(desc_buf
);
546 pdev_obj
= umss_create_device(dev_mgr
, pdrvr
, dev_handle
, FALSE
);
548 lock_dev(pdev
, FALSE
);
549 if (pdev_obj
== NULL
||
550 dev_state(pdev
) == USB_DEV_STATE_ZOMB
||
551 dev_mgr_set_driver(dev_mgr
, dev_handle
, pdrvr
, pdev
) == FALSE
)
553 usb_free_mem(desc_buf
);
554 unlock_dev(pdev
, FALSE
);
557 umss_delete_device(dev_mgr
, pdrvr
, pdev_obj
, FALSE
);
559 usb_unlock_dev(pdev
);
562 unlock_dev(pdev
, FALSE
);
564 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) pdev_obj
->DeviceExtension
;
566 pdev_ext
->desc_buf
= desc_buf
;
567 pdev_ext
->pif_desc
= NULL
;
568 pdev_ext
->pin_endp_desc
= pdev_ext
->pout_endp_desc
= NULL
;
570 pconfig_desc
= (PUSB_CONFIGURATION_DESC
) desc_buf
;
571 pif_desc
= (PUSB_INTERFACE_DESC
) (&pconfig_desc
[1]);
573 for(i
= 0; ((UCHAR
) i
) < pconfig_desc
->bNumInterfaces
; i
++)
575 if (pif_desc
->bLength
== sizeof(USB_INTERFACE_DESC
) && pif_desc
->bDescriptorType
== USB_DT_INTERFACE
)
577 if (pif_desc
->bInterfaceClass
== USB_CLASS_MASS_STORAGE
)
579 pdev_ext
->pif_desc
= pif_desc
;
580 pdev_ext
->if_idx
= (UCHAR
) i
;
585 if (usb_skip_if_and_altif((PUCHAR
*) & pif_desc
) == FALSE
)
595 if (pdev_ext
->pif_desc
)
597 pendp_desc
= (PUSB_ENDPOINT_DESC
) & pif_desc
[1];
598 for(i
= 0; ((UCHAR
) i
) < pif_desc
->bNumEndpoints
; i
++)
600 if (pendp_desc
->bDescriptorType
== USB_DT_ENDPOINT
601 && pendp_desc
->bLength
== sizeof(USB_ENDPOINT_DESC
))
603 if ((pendp_desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_INT
)
605 pdev_ext
->pint_endp_desc
= pendp_desc
;
606 pdev_ext
->int_endp_idx
= (UCHAR
) i
;
608 else if ((pendp_desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_BULK
)
610 if (pendp_desc
->bEndpointAddress
& USB_DIR_IN
)
612 pdev_ext
->pin_endp_desc
= pendp_desc
;
613 pdev_ext
->in_endp_idx
= (UCHAR
) i
;
617 pdev_ext
->pout_endp_desc
= pendp_desc
;
618 pdev_ext
->out_endp_idx
= (UCHAR
) i
;
621 pendp_desc
= &pendp_desc
[1];
627 usb_unlock_dev(pdev
);
632 umss_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
634 UNREFERENCED_PARAMETER(dev_handle
);
635 UNREFERENCED_PARAMETER(dev_mgr
);
640 umss_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
642 PDEVICE_OBJECT dev_obj
;
647 if (dev_mgr
== NULL
|| dev_handle
== 0)
651 //special use of the lock dev, simply use this routine to get the dev
652 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
657 if (status
== STATUS_SUCCESS
)
661 usb_unlock_dev(pdev
);
663 pdrvr
= pdev
->dev_driver
;
664 dev_obj
= pdev
->dev_obj
;
667 return umss_delete_device(dev_mgr
, pdrvr
, dev_obj
, FALSE
);
671 umss_deferred_delete_device(PVOID context
)
673 PDEVICE_OBJECT dev_obj
;
674 PUMSS_DEVICE_EXTENSION pdev_ext
;
675 PUMSS_DRVR_EXTENSION pdrvr_ext
;
676 LARGE_INTEGER interval
;
681 dev_obj
= (PDEVICE_OBJECT
) context
;
682 pdev_ext
= dev_obj
->DeviceExtension
;
683 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdev_ext
->pdriver
->driver_ext
;
685 interval
.QuadPart
= -20000; //two ms
689 if (dev_obj
->ReferenceCount
)
690 KeDelayExecutionThread(KernelMode
, TRUE
, &interval
);
693 KeDelayExecutionThread(KernelMode
, TRUE
, &interval
);
694 if (dev_obj
->ReferenceCount
== 0)
698 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_deferred_delete_device(): delete device, 0x%x\n", dev_obj
));
700 ExAcquireFastMutex(&pdrvr_ext
->dev_list_mutex
);
701 RemoveEntryList(&pdev_ext
->dev_obj_link
);
702 pdrvr_ext
->dev_count
--;
703 ExReleaseFastMutex(&pdrvr_ext
->dev_list_mutex
);
705 IoDeleteDevice(dev_obj
);
710 umss_delete_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdrvr
, PDEVICE_OBJECT dev_obj
, BOOLEAN is_if
)
714 UNICODE_STRING symb_link
;
715 PUMSS_DEVICE_EXTENSION pdev_ext
;
716 PUMSS_DRVR_EXTENSION pdrvr_ext
;
721 if (pdrvr
== NULL
|| dev_mgr
== NULL
)
724 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) dev_obj
->DeviceExtension
;
725 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdrvr
->driver_ext
;
727 sprintf(dev_name
, "\\DosDevices\\umssdev%d", (int)pdev_ext
->umss_dev_id
);
729 sprintf(dev_name
, "\\DosDevices\\umssifdev%d", (int)pdev_ext
->umss_dev_id
);
731 RtlInitString(&string
, dev_name
);
732 RtlAnsiStringToUnicodeString(&symb_link
, &string
, TRUE
);
733 IoDeleteSymbolicLink(&symb_link
);
734 RtlFreeUnicodeString(&symb_link
);
736 if (pdev_ext
->desc_buf
)
738 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_delete_device(): delete desc_buf\n"));
739 usb_free_mem(pdev_ext
->desc_buf
);
740 pdev_ext
->desc_buf
= NULL
;
744 if (dev_obj
->ReferenceCount
== 0)
746 ExAcquireFastMutex(&pdrvr_ext
->dev_list_mutex
);
747 RemoveEntryList(&pdev_ext
->dev_obj_link
);
748 pdrvr_ext
->dev_count
--;
749 ExReleaseFastMutex(&pdrvr_ext
->dev_list_mutex
);
751 IoDeleteDevice(dev_obj
);
756 // FIXME: how if the driver unloading happens
757 // since this is called in dev_mgr_disconnect_dev, umss_schedule_workitem
758 // can not protect the USB_DEV object from be deleted. so the workitem
759 // can not access anything relative to the USB_DEV object. In this case
760 // we will tollerate the usb_query_and_lock_dev failure since it will
761 // never success when come to this point, and we won't pass dev_mgr
762 // and pdev to the function. But other scenarios, usb_query_and_lock_dev
763 // can not fail if dev_mgr and pdev are passed valid.
764 // When driver is unloading, don't know. Wish NT will unload the driver
765 // only when all the devices to the driver are deleted.
767 umss_schedule_workitem(dev_obj
, umss_deferred_delete_device
, NULL
, 0);
772 umss_submit_io_packet(PDEVICE_OBJECT dev_obj
, PIO_PACKET io_packet
)
775 PUMSS_DEVICE_EXTENSION pdev_ext
;
778 pdev_ext
= dev_obj
->DeviceExtension
;
780 // lock the dev, the pdev_ext->pif_desc won't go away.
781 if ((status
= usb_query_and_lock_dev(pdev_ext
->dev_mgr
, pdev_ext
->dev_handle
, &pdev
)) != STATUS_SUCCESS
)
783 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_start_io(): error, device is not valid\n"));
784 UMSS_COMPLETE_START_IO(dev_obj
, status
, io_packet
->pirp
);
788 if (pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_BULKONLY
)
790 status
= umss_bulkonly_startio(pdev_ext
, io_packet
);
792 else if (pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_CB
793 || pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_CBI
)
795 status
= umss_cbi_startio(pdev_ext
, io_packet
);
799 status
= STATUS_DEVICE_PROTOCOL_ERROR
;
801 usb_unlock_dev(pdev
);
802 UMSS_COMPLETE_START_IO(dev_obj
, status
, io_packet
->pirp
);
808 umss_start_io(IN PDEVICE_OBJECT dev_obj
, IN PIRP irp
)
812 PIO_STACK_LOCATION irp_stack
;
813 PUMSS_DEVICE_EXTENSION pdev_ext
;
815 PUSER_IO_PACKET user_io_packet
;
817 if (dev_obj
== NULL
|| irp
== NULL
)
820 status
= STATUS_SUCCESS
;
822 irp_stack
= IoGetCurrentIrpStackLocation(irp
);
823 ctrl_code
= irp_stack
->Parameters
.DeviceIoControl
.IoControlCode
;
824 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) dev_obj
->DeviceExtension
;
826 if (irp_stack
->MajorFunction
== IRP_MJ_SCSI
)
828 umss_process_srb(dev_obj
, irp
);
832 if (irp_stack
->MajorFunction
!= IRP_MJ_DEVICE_CONTROL
)
834 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_DEVICE_REQUEST
, irp
);
839 case IOCTL_UMSS_SUBMIT_CDB_IN
:
840 case IOCTL_UMSS_SUBMIT_CDB_OUT
:
841 case IOCTL_UMSS_SUBMIT_CDB
:
843 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(USER_IO_PACKET
))
845 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_PARAMETER
, irp
);
848 user_io_packet
= (PUSER_IO_PACKET
) irp
->AssociatedIrp
.SystemBuffer
;
850 if (user_io_packet
->sub_class
!= pdev_ext
->pif_desc
->bInterfaceSubClass
)
852 // not agree with the dev's subclass
853 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_DEVICE_PROTOCOL_ERROR
, irp
);
856 RtlZeroMemory(&io_packet
, sizeof(io_packet
));
857 io_packet
.cdb_length
= user_io_packet
->cdb_length
;
858 io_packet
.lun
= user_io_packet
->lun
;
860 RtlCopyMemory(io_packet
.cdb
, user_io_packet
->cdb
, MAX_CDB_LENGTH
);
862 if (ctrl_code
== IOCTL_UMSS_SUBMIT_CDB_IN
)
863 io_packet
.flags
|= USB_DIR_IN
;
865 if (ctrl_code
!= IOCTL_UMSS_SUBMIT_CDB
)
867 if (irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
== 0)
868 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_BUFFER_TOO_SMALL
, irp
);
870 io_packet
.data_buffer
= MmGetSystemAddressForMdl(irp
->MdlAddress
);
871 io_packet
.data_length
= irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
873 if (io_packet
.data_length
> MAX_BULK_TRANSFER_LENGTH
)
874 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_BUFFER_TOO_SMALL
, irp
);
876 //synchronize the buffer
877 if (io_packet
.flags
& USB_DIR_IN
)
878 KeFlushIoBuffers(irp
->MdlAddress
, TRUE
, TRUE
);
880 KeFlushIoBuffers(irp
->MdlAddress
, FALSE
, TRUE
);
883 io_packet
.pirp
= irp
;
884 umss_submit_io_packet(dev_obj
, &io_packet
);
887 case IOCTL_SCSI_PASS_THROUGH
:
889 PSCSI_PASS_THROUGH pass_through
;
892 pass_through
= irp
->AssociatedIrp
.SystemBuffer
;
894 if (pass_through
->DataTransferLength
&&
895 pass_through
->DataBufferOffset
!= sizeof(SCSI_PASS_THROUGH
))
896 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_PARAMETER
, irp
);
898 if (pass_through
->SenseInfoLength
&&
899 (pass_through
->SenseInfoOffset
!=
900 pass_through
->DataBufferOffset
+ pass_through
->DataTransferLength
))
901 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_PARAMETER
, irp
);
903 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
<
904 (sizeof(SCSI_PASS_THROUGH
) +
905 pass_through
->SenseInfoLength
+ pass_through
->DataTransferLength
))
906 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_BUFFER_TOO_SMALL
, irp
);
908 RtlZeroMemory(&io_packet
, sizeof(io_packet
));
910 io_packet
.flags
|= IOP_FLAG_SCSI_CTRL_TRANSFER
;
911 if (pass_through
->DataIn
)
912 io_packet
.flags
|= IOP_FLAG_DIR_IN
;
914 io_packet
.data_buffer
= (PVOID
) & pass_through
[1];
915 io_packet
.data_length
= pass_through
->DataTransferLength
;
917 if (pass_through
->SenseInfoLength
)
919 io_packet
.sense_data
= ((PUCHAR
) pass_through
) + pass_through
->SenseInfoOffset
;
920 io_packet
.sense_data_length
= pass_through
->SenseInfoLength
;
921 io_packet
.flags
|= IOP_FLAG_REQ_SENSE
;
924 io_packet
.cdb_length
= pass_through
->CdbLength
;
925 RtlCopyMemory(io_packet
.cdb
, pass_through
->Cdb
, sizeof(io_packet
.cdb
));
927 io_packet
.pirp
= irp
;
928 umss_submit_io_packet(dev_obj
, &io_packet
);
931 case IOCTL_SCSI_PASS_THROUGH_DIRECT
:
933 PSCSI_PASS_THROUGH_DIRECT pass_through_direct
;
936 pass_through_direct
= irp
->AssociatedIrp
.SystemBuffer
;
938 if (pass_through_direct
->SenseInfoLength
&&
939 pass_through_direct
->SenseInfoOffset
!= sizeof(SCSI_PASS_THROUGH_DIRECT
))
940 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_PARAMETER
, irp
);
942 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
<
943 sizeof(SCSI_PASS_THROUGH_DIRECT
) + pass_through_direct
->SenseInfoLength
)
944 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_BUFFER_TOO_SMALL
, irp
);
946 RtlZeroMemory(&io_packet
, sizeof(io_packet
));
948 io_packet
.flags
|= IOP_FLAG_SCSI_CTRL_TRANSFER
;
949 if (pass_through_direct
->DataIn
)
950 io_packet
.flags
|= IOP_FLAG_DIR_IN
;
952 io_packet
.data_buffer
= pass_through_direct
->DataBuffer
;
953 io_packet
.data_length
= pass_through_direct
->DataTransferLength
;
955 if (pass_through_direct
->SenseInfoLength
)
957 io_packet
.sense_data
= ((PUCHAR
) pass_through_direct
) + pass_through_direct
->SenseInfoOffset
;
958 io_packet
.sense_data_length
= pass_through_direct
->SenseInfoLength
;
959 io_packet
.flags
|= IOP_FLAG_REQ_SENSE
;
962 io_packet
.cdb_length
= pass_through_direct
->CdbLength
;
963 RtlCopyMemory(io_packet
.cdb
, pass_through_direct
->Cdb
, sizeof(io_packet
.cdb
));
965 io_packet
.pirp
= irp
;
966 umss_submit_io_packet(dev_obj
, &io_packet
);
969 case IOCTL_SUBMIT_URB_RD
:
970 case IOCTL_SUBMIT_URB_NOIO
:
971 case IOCTL_SUBMIT_URB_WR
:
973 gendrv_startio(dev_obj
, irp
);
977 UMSS_COMPLETE_START_IO(dev_obj
, STATUS_INVALID_DEVICE_REQUEST
, irp
);
982 // bugbug!!! there can not be sent IOCTL_SUBMIT_URB_XXX while
983 // the IOCTL_SUBMIT_CDB_XXX are active. may confuse the device.
986 umss_dispatch_routine(PDEVICE_OBJECT pdev_obj
, PIRP irp
)
990 PIO_STACK_LOCATION irp_stack
;
991 PUMSS_DEVICE_EXTENSION pdev_ext
;
992 USE_BASIC_NON_PENDING_IRQL
;
994 if (pdev_obj
== NULL
|| irp
== NULL
)
995 return STATUS_INVALID_PARAMETER
;
997 status
= STATUS_SUCCESS
;
998 irp_stack
= IoGetCurrentIrpStackLocation(irp
);
999 ctrl_code
= irp_stack
->Parameters
.DeviceIoControl
.IoControlCode
;
1001 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) pdev_obj
->DeviceExtension
;
1003 switch (irp_stack
->MajorFunction
)
1008 return dev_mgr_dispatch(pdev_ext
->dev_mgr
, irp
);
1010 case IRP_MJ_INTERNAL_DEVICE_CONTROL
:
1012 // function code to receive scsi request
1013 UMSS_EXIT_DISPATCH(pdev_obj
, STATUS_PENDING
, irp
);
1015 case IRP_MJ_DEVICE_CONTROL
:
1019 case IOCTL_UMSS_SET_FDO
:
1024 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(PDEVICE_OBJECT
))
1026 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1029 fdo
= (PDEVICE_OBJECT
) ((PULONG
) irp
->AssociatedIrp
.SystemBuffer
)[0];
1031 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1033 // we have to test the usb dev's state to determine whether set or not the fdo
1036 if (usb_query_and_lock_dev(pdev_ext
->dev_mgr
, pdev_ext
->dev_handle
, &pdev
) !=
1038 EXIT_DISPATCH(STATUS_DEVICE_DOES_NOT_EXIST
, irp
);
1040 lock_dev(pdev
, FALSE
);
1042 if (dev_state(pdev
) >= USB_DEV_STATE_BEFORE_ZOMB
|| dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1044 unlock_dev(pdev
, FALSE
);
1045 usb_unlock_dev(pdev
);
1046 EXIT_DISPATCH(STATUS_DEVICE_DOES_NOT_EXIST
, irp
);
1049 pdev_ext
->fdo
= fdo
;
1050 unlock_dev(pdev
, FALSE
);
1051 usb_unlock_dev(pdev
);
1052 irp
->IoStatus
.Information
= 0;
1053 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1056 case IOCTL_GET_DEV_DESC
:
1058 PGET_DEV_DESC_REQ pgddr
;
1059 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(GET_DEV_DESC_REQ
))
1061 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1063 pgddr
= irp
->AssociatedIrp
.SystemBuffer
;
1064 if (pgddr
->dev_handle
!= (pdev_ext
->dev_handle
& 0xffff0000))
1066 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1068 // an immediate request
1069 return dev_mgr_dispatch(pdev_ext
->dev_mgr
, irp
);
1071 case IOCTL_SUBMIT_URB_RD
:
1072 case IOCTL_SUBMIT_URB_NOIO
:
1073 case IOCTL_SUBMIT_URB_WR
:
1076 DEV_HANDLE endp_handle
;
1078 if (irp_stack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(URB
))
1080 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1083 purb
= (PURB
) irp
->AssociatedIrp
.SystemBuffer
;
1084 endp_handle
= purb
->endp_handle
;
1085 if (!default_endp_handle(endp_handle
))
1087 //no permit to other interface if interface dev
1088 if ((pdev_ext
->flags
& UMSS_DEV_FLAG_IF_DEV
)
1089 && if_idx_from_handle(endp_handle
) != pdev_ext
->if_idx
)
1090 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1092 // FIXME: this is dangeous
1093 // return dev_mgr_dispatch( pdev_ext->dev_mgr, irp );
1094 UMSS_EXIT_DISPATCH(pdev_obj
, STATUS_PENDING
, irp
);
1096 case IOCTL_GET_DEV_HANDLE
:
1098 if (irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(LONG
))
1099 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1101 *((PLONG
) irp
->AssociatedIrp
.SystemBuffer
) = pdev_ext
->dev_handle
;
1102 irp
->IoStatus
.Information
= sizeof(LONG
);
1103 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1107 // request from scsi class driver
1109 case IOCTL_SCSI_PASS_THROUGH
:
1110 case IOCTL_SCSI_PASS_THROUGH_DIRECT
:
1112 // direct cdb request
1114 case IOCTL_UMSS_SUBMIT_CDB
:
1115 case IOCTL_UMSS_SUBMIT_CDB_OUT
:
1116 case IOCTL_UMSS_SUBMIT_CDB_IN
:
1118 UMSS_EXIT_DISPATCH(pdev_obj
, STATUS_PENDING
, irp
);
1120 case IOCTL_SCSI_GET_INQUIRY_DATA
:
1122 PSCSI_ADAPTER_BUS_INFO adapter_info
;
1123 PSCSI_BUS_DATA bus_data
;
1124 PSCSI_INQUIRY_DATA inq_dat
;
1126 IO_PACKET io_packet
;
1127 ULONG required_size
;
1129 required_size
= sizeof(SCSI_ADAPTER_BUS_INFO
)
1130 + sizeof(SCSI_BUS_DATA
) + sizeof(SCSI_INQUIRY_DATA
) + INQUIRYDATABUFFERSIZE
;
1132 if (irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
< required_size
)
1133 UMSS_EXIT_DISPATCH(pdev_obj
, STATUS_BUFFER_TOO_SMALL
, irp
);
1135 RtlZeroMemory(&io_packet
, sizeof(io_packet
));
1137 adapter_info
= irp
->AssociatedIrp
.SystemBuffer
;
1138 adapter_info
->NumberOfBuses
= 1;
1139 bus_data
= &adapter_info
->BusData
[0];
1140 bus_data
->NumberOfLogicalUnits
= 1;
1141 bus_data
->InitiatorBusId
= 0;
1142 bus_data
->InquiryDataOffset
= sizeof(SCSI_ADAPTER_BUS_INFO
);
1143 inq_dat
= (PVOID
) & bus_data
[1];
1144 inq_dat
->PathId
= 0;
1145 inq_dat
->TargetId
= pdev_ext
->umss_dev_id
;
1147 // this is the dev_id for usb dev_manager
1149 inq_dat
->Lun
= (UCHAR
) (pdev_ext
->dev_handle
>> 16);
1150 inq_dat
->DeviceClaimed
= FALSE
;
1151 inq_dat
->InquiryDataLength
= 36;
1152 inq_dat
->NextInquiryDataOffset
= 0;
1153 inq
= (PINQUIRYDATA
) inq_dat
->InquiryData
;
1155 RtlZeroMemory(inq
, sizeof(INQUIRYDATA
));
1156 inq
->DeviceType
= DIRECT_ACCESS_DEVICE
;
1157 inq
->DeviceTypeQualifier
= 0;
1158 inq
->RemovableMedia
= 1;
1161 // pretend to comply scsi primary 2 command set
1164 inq
->Versions
= 0x04;
1167 // the format is in scsi-2 format
1170 inq
->ResponseDataFormat
= 0x02;
1173 // we are the poor scsi device
1176 inq
->AdditionalLength
= 31;
1178 inq
->CommandQueue
= 0;
1179 inq
->LinkedCommands
= 0;
1180 inq
->RelativeAddressing
= 0;
1181 RtlCopyMemory(&inq
->VendorId
, "Unknown", 7);
1182 RtlCopyMemory(&inq
->ProductId
, "USB Mass Storage", 16);
1183 irp
->IoStatus
.Information
= required_size
;
1184 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1186 case IOCTL_SCSI_GET_CAPABILITIES
:
1188 PIO_SCSI_CAPABILITIES port_cap
;
1190 if (irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
<
1191 sizeof(IO_SCSI_CAPABILITIES
))
1192 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1194 port_cap
= (PIO_SCSI_CAPABILITIES
) irp
->AssociatedIrp
.SystemBuffer
;
1195 port_cap
->Length
= sizeof(IO_SCSI_CAPABILITIES
);
1196 port_cap
->MaximumTransferLength
= 65536;
1197 port_cap
->MaximumPhysicalPages
= 65536 / PAGE_SIZE
;
1198 port_cap
->SupportedAsynchronousEvents
= 0;
1199 port_cap
->AlignmentMask
= 0x10;
1200 port_cap
->TaggedQueuing
= FALSE
;
1201 port_cap
->AdapterScansDown
= FALSE
;
1202 port_cap
->AdapterUsesPio
= FALSE
;
1203 irp
->IoStatus
.Information
= sizeof(IO_SCSI_CAPABILITIES
);
1204 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1206 case IOCTL_SCSI_GET_ADDRESS
:
1208 PSCSI_ADDRESS paddr
;
1209 if (irp_stack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(SCSI_ADDRESS
))
1210 EXIT_DISPATCH(STATUS_INVALID_PARAMETER
, irp
);
1212 paddr
= (PSCSI_ADDRESS
) irp
->AssociatedIrp
.SystemBuffer
;
1214 paddr
->Length
= sizeof(SCSI_ADDRESS
);
1215 paddr
->PortNumber
= 0;
1217 paddr
->TargetId
= pdev_ext
->umss_dev_id
;
1218 paddr
->Lun
= (UCHAR
) (pdev_ext
->dev_handle
>> 16);
1219 irp
->IoStatus
.Information
= sizeof(SCSI_ADDRESS
);
1220 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1222 case IOCTL_SCSI_RESCAN_BUS
:
1224 irp
->IoStatus
.Information
= 0;
1225 EXIT_DISPATCH(STATUS_SUCCESS
, irp
);
1229 EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST
, irp
);
1234 EXIT_DISPATCH(STATUS_NOT_SUPPORTED
, irp
);
1238 umss_reset_pipe_completion(PURB purb
, PVOID context
)
1240 PUMSS_DEVICE_EXTENSION pdev_ext
;
1241 if (context
== NULL
)
1244 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) context
;
1245 pdev_ext
->reset_pipe_status
= purb
->status
;
1246 KeSetEvent(&pdev_ext
->sync_event
, 0, FALSE
);
1250 //can only be called at passive level
1252 umss_reset_pipe(PUMSS_DEVICE_EXTENSION pdev_ext
, DEV_HANDLE endp_handle
)
1257 if (pdev_ext
== NULL
)
1258 return STATUS_INVALID_PARAMETER
;
1260 status
= usb_query_and_lock_dev(pdev_ext
->dev_mgr
, pdev_ext
->dev_handle
, &pdev
);
1262 if (status
!= STATUS_SUCCESS
)
1263 return STATUS_UNSUCCESSFUL
;
1265 status
= usb_reset_pipe_ex(pdev_ext
->dev_mgr
, endp_handle
, umss_reset_pipe_completion
, pdev_ext
);
1267 if (status
== STATUS_PENDING
)
1269 KeWaitForSingleObject(&pdev_ext
->sync_event
, Executive
, KernelMode
, TRUE
, NULL
);
1270 status
= pdev_ext
->reset_pipe_status
;
1272 usb_unlock_dev(pdev
);
1277 umss_gen_result_srb(PIO_PACKET io_packet
, PSCSI_REQUEST_BLOCK srb
, NTSTATUS status
)
1280 if (srb
== NULL
|| io_packet
== NULL
)
1284 if (status
== STATUS_SUCCESS
)
1286 PULONG dest_buf
, src_buf
;
1289 srb
->SrbStatus
= SRB_STATUS_SUCCESS
;
1291 io_packet
->pirp
->IoStatus
.Information
= srb
->DataTransferLength
;
1292 if ((io_packet
->pirp
->Flags
& IRP_READ_OPERATION
) && !(io_packet
->pirp
->Flags
& IRP_PAGING_IO
))
1294 src_buf
= (PULONG
) io_packet
->data_buffer
;
1295 dest_buf
= (PULONG
) srb
->DataBuffer
;
1296 if (src_buf
&& dest_buf
)
1298 for(i
= 0; i
< (srb
->DataTransferLength
>> 2); i
++)
1300 dest_buf
[i
] = src_buf
[i
];
1305 else if (status
== STATUS_DEVICE_DOES_NOT_EXIST
)
1307 PSENSE_DATA sense_buf
;
1308 srb
->SrbStatus
= SRB_STATUS_NO_DEVICE
;
1309 srb
->ScsiStatus
= SCSISTAT_CHECK_CONDITION
;
1312 // let's build the srb status for class driver
1315 srb
->SrbStatus
|= SRB_STATUS_AUTOSENSE_VALID
;
1316 sense_buf
= (PSENSE_DATA
) srb
->SenseInfoBuffer
;
1318 if (!(srb
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
))
1320 RtlZeroMemory(srb
->SenseInfoBuffer
, srb
->SenseInfoBufferLength
);
1321 sense_buf
->ErrorCode
= 0x70;
1322 sense_buf
->Valid
= 1;
1323 sense_buf
->SenseKey
= SCSI_SENSE_NOT_READY
;
1324 sense_buf
->AdditionalSenseCode
= SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
;
1325 sense_buf
->AdditionalSenseLength
= 10;
1328 else if (status
== USB_STATUS_STALL_PID
|| status
== USB_STATUS_CRC
||
1329 status
== USB_STATUS_BTSTUFF
|| status
== USB_STATUS_DATA_OVERRUN
)
1331 PSENSE_DATA sense_buf
;
1332 srb
->SrbStatus
= SRB_STATUS_ERROR
;
1333 srb
->ScsiStatus
= SCSISTAT_CHECK_CONDITION
;
1335 srb
->SrbStatus
|= SRB_STATUS_AUTOSENSE_VALID
;
1336 sense_buf
= (PSENSE_DATA
) srb
->SenseInfoBuffer
;
1338 if (!(srb
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
))
1340 RtlZeroMemory(srb
->SenseInfoBuffer
, srb
->SenseInfoBufferLength
);
1341 sense_buf
->ErrorCode
= 0x70;
1342 sense_buf
->Valid
= 1;
1343 sense_buf
->SenseKey
= SCSI_SENSE_HARDWARE_ERROR
;
1344 sense_buf
->AdditionalSenseCode
= 0;
1345 sense_buf
->AdditionalSenseLength
= 10;
1350 srb
->SrbStatus
= SRB_STATUS_ERROR
;
1353 if ((io_packet
->pirp
->Flags
& (IRP_READ_OPERATION
| IRP_WRITE_OPERATION
))
1354 && !(io_packet
->pirp
->Flags
& IRP_PAGING_IO
))
1356 if (io_packet
->data_buffer
)
1358 usb_free_mem(io_packet
->data_buffer
);
1359 io_packet
->data_buffer
= NULL
;
1366 umss_gen_result_ctrl(PDEVICE_OBJECT dev_obj
, PIRP irp
, NTSTATUS status
)
1368 PIO_STACK_LOCATION irp_stack
;
1370 PUMSS_DEVICE_EXTENSION pdev_ext
;
1375 irp
->IoStatus
.Information
= 0;
1376 irp_stack
= IoGetCurrentIrpStackLocation(irp
);
1377 ctrl_code
= irp_stack
->Parameters
.DeviceIoControl
.IoControlCode
;
1378 pdev_ext
= dev_obj
->DeviceExtension
;
1382 case IOCTL_SCSI_PASS_THROUGH
:
1384 PSCSI_PASS_THROUGH pass_through
;
1385 pass_through
= irp
->AssociatedIrp
.SystemBuffer
;
1386 irp
->IoStatus
.Status
= status
;
1388 // we have set these two value in bulkonly.c when data transfer complete
1389 // pass_through_direct->DataTransferLength = pdev_ext->io_packet.data_length;
1390 // pass_through_direct->SenseInfoLength = pdev_ext->io_packet.sense_data_length;
1392 if (status
== STATUS_SUCCESS
)
1393 irp
->IoStatus
.Information
= pass_through
->SenseInfoOffset
+ pass_through
->SenseInfoLength
;
1395 pass_through
->ScsiStatus
= SCSISTAT_CHECK_CONDITION
;
1398 case IOCTL_SCSI_PASS_THROUGH_DIRECT
:
1400 PSCSI_PASS_THROUGH_DIRECT pass_through_direct
;
1402 pass_through_direct
= irp
->AssociatedIrp
.SystemBuffer
;
1403 pass_through_direct
->ScsiStatus
= 0;
1404 irp
->IoStatus
.Status
= status
;
1406 // we have set these two value in bulkonly.c when data transfer complete
1407 // pass_through_direct->DataTransferLength = pdev_ext->io_packet.data_length;
1408 // pass_through_direct->SenseInfoLength = pdev_ext->io_packet.sense_data_length;
1410 if (status
== STATUS_SUCCESS
)
1411 irp
->IoStatus
.Information
=
1412 pass_through_direct
->SenseInfoOffset
+ pass_through_direct
->SenseInfoLength
;
1414 pass_through_direct
->ScsiStatus
= SCSISTAT_CHECK_CONDITION
;
1424 umss_complete_request(PUMSS_DEVICE_EXTENSION pdev_ext
, NTSTATUS status
)
1429 PDEVICE_OBJECT dev_obj
;
1430 PIO_STACK_LOCATION irp_stack
;
1432 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_complete_request(): entering...\n"));
1434 pirp
= pdev_ext
->io_packet
.pirp
;
1435 dev_obj
= pdev_ext
->pdo
;
1437 irp_stack
= IoGetCurrentIrpStackLocation(pirp
);
1439 if (pdev_ext
->io_packet
.flags
& IOP_FLAG_SRB_TRANSFER
)
1441 if (pdev_ext
->pif_desc
->bInterfaceSubClass
== UMSS_SUBCLASS_SFF8070I
)
1443 umss_fix_sff_result(&pdev_ext
->io_packet
, irp_stack
->Parameters
.Scsi
.Srb
);
1445 umss_gen_result_srb(&pdev_ext
->io_packet
, irp_stack
->Parameters
.Scsi
.Srb
, status
);
1447 else if (pdev_ext
->io_packet
.flags
& IOP_FLAG_SCSI_CTRL_TRANSFER
)
1448 umss_gen_result_ctrl(dev_obj
, pirp
, status
);
1450 //this device has its irp queued
1451 if (status
== STATUS_CANCELLED
)
1453 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_complete_request(): status of irp is cancelled\n"));
1454 IoAcquireCancelSpinLock(&old_irql
);
1455 if (dev_obj
->CurrentIrp
== pirp
)
1457 IoReleaseCancelSpinLock(old_irql
);
1458 IoStartNextPacket(dev_obj
, FALSE
);
1462 KeRemoveEntryDeviceQueue(&dev_obj
->DeviceQueue
, &pirp
->Tail
.Overlay
.DeviceQueueEntry
);
1463 IoReleaseCancelSpinLock(old_irql
);
1468 // all requests come to this point from the irp queue
1469 IoStartNextPacket(dev_obj
, FALSE
);
1471 // we are going to complete the request, so set it's cancel routine to NULL
1472 IoAcquireCancelSpinLock(&old_irql
);
1473 (void)IoSetCancelRoutine(pirp
, NULL
);
1474 IoReleaseCancelSpinLock(old_irql
);
1477 pirp
->IoStatus
.Status
= status
;
1479 if (status
!= STATUS_SUCCESS
)
1480 pirp
->IoStatus
.Information
= 0;
1482 IoCompleteRequest(pirp
, IO_NO_INCREMENT
);
1487 umss_if_connect(PDEV_CONNECT_DATA params
, DEV_HANDLE if_handle
)
1495 PUSB_INTERFACE_DESC pif_desc
;
1496 PUSB_CTRL_SETUP_PACKET psetup
;
1497 PUMSS_DEVICE_EXTENSION pdev_ext
;
1498 PUSB_CONFIGURATION_DESC pconfig_desc
;
1499 PUSB_DEV_MANAGER dev_mgr
;
1500 PUSB_ENDPOINT_DESC pendp_desc
;
1501 PUMSS_DRVR_EXTENSION pdrvr_ext
;
1502 PDEVICE_OBJECT pdev_obj
;
1503 USE_BASIC_NON_PENDING_IRQL
;
1505 //configuration is already set
1510 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_if_connect(): entering...\n"));
1515 dev_mgr
= params
->dev_mgr
;
1516 pdrvr
= params
->pdriver
;
1518 if_idx
= if_idx_from_handle(if_handle
);
1520 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
1524 desc_buf
= usb_alloc_mem(NonPagedPool
, 512);
1525 if (desc_buf
== NULL
)
1528 psetup
= (PUSB_CTRL_SETUP_PACKET
) (purb
)->setup_packet
;
1531 // now let's get the descs, one configuration, one interface and two endpoint
1532 psetup
= (PUSB_CTRL_SETUP_PACKET
) (purb
)->setup_packet
;
1533 purb
->endp_handle
= if_handle
| 0xffff;
1534 purb
->data_buffer
= desc_buf
;
1535 purb
->data_length
= 512;
1536 purb
->completion
= NULL
; // this is an immediate request, no needs completion
1537 purb
->context
= dev_mgr
;
1538 purb
->reference
= 0;
1539 psetup
->bmRequestType
= 0x80;
1540 psetup
->bRequest
= USB_REQ_GET_DESCRIPTOR
;
1541 psetup
->wValue
= USB_DT_CONFIG
<< 8;
1543 psetup
->wLength
= 512;
1545 status
= usb_submit_urb(dev_mgr
, purb
);
1546 if (status
== STATUS_PENDING
)
1553 if (status
!= STATUS_SUCCESS
)
1558 status
= usb_query_and_lock_dev(dev_mgr
, if_handle
, &pdev
);
1559 if (status
!= STATUS_SUCCESS
)
1564 #ifdef _TIANSHENG_DRIVER
1565 if (!((pdev
->pusb_dev_desc
->idVendor
== 0x03eb && pdev
->pusb_dev_desc
->idProduct
== 0x2002)
1566 || (pdev
->pusb_dev_desc
->idVendor
== 0x0ea0 && pdev
->pusb_dev_desc
->idProduct
== 0x6803)
1567 || (pdev
->pusb_dev_desc
->idVendor
== 0x0ef5 && pdev
->pusb_dev_desc
->idProduct
== 0x2202)))
1569 // check TianSheng's product
1574 pdev_obj
= umss_create_device(dev_mgr
, pdrvr
, if_handle
, TRUE
);
1575 if (pdev_obj
== NULL
)
1580 lock_dev(pdev
, FALSE
);
1581 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
||
1582 dev_mgr_set_if_driver(dev_mgr
, if_handle
, pdrvr
, pdev
) == FALSE
)
1584 unlock_dev(pdev
, FALSE
);
1587 umss_delete_device(dev_mgr
, pdrvr
, pdev_obj
, TRUE
);
1592 if (pdev
->usb_config
)
1594 pdev
->usb_config
->interf
[if_idx
].if_ext
= pdev_obj
;
1595 pdev
->usb_config
->interf
[if_idx
].if_ext_size
= 0;
1597 // olympus dev needs special care
1598 if (UMSS_OLYMPUS_VENDOR_ID
== pdev
->pusb_dev_desc
->idVendor
)
1603 unlock_dev(pdev
, FALSE
);
1605 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) pdev_obj
->DeviceExtension
;
1607 pdev_ext
->desc_buf
= desc_buf
;
1608 pdev_ext
->pif_desc
= NULL
;
1609 pdev_ext
->pin_endp_desc
= pdev_ext
->pout_endp_desc
= NULL
;
1610 pconfig_desc
= (PUSB_CONFIGURATION_DESC
) desc_buf
;
1611 pif_desc
= (PUSB_INTERFACE_DESC
) (&pconfig_desc
[1]);
1614 pdev_ext
->flags
|= UMSS_DEV_FLAG_OLYMPUS_DEV
;
1617 for(i
= 0; ((UCHAR
) i
) < if_idx
; i
++)
1619 if (usb_skip_if_and_altif((PUCHAR
*) & pif_desc
) == FALSE
)
1622 pdev_ext
->pif_desc
= pif_desc
;
1624 if (pdev_ext
->pif_desc
)
1626 pendp_desc
= (PUSB_ENDPOINT_DESC
) & pif_desc
[1];
1627 for(i
= 0; ((UCHAR
) i
) < pif_desc
->bNumEndpoints
; i
++)
1629 if (pendp_desc
->bDescriptorType
== USB_DT_ENDPOINT
1630 && pendp_desc
->bLength
== sizeof(USB_ENDPOINT_DESC
))
1632 if ((pendp_desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_INT
)
1634 pdev_ext
->pint_endp_desc
= pendp_desc
;
1635 pdev_ext
->int_endp_idx
= (UCHAR
) i
;
1637 else if ((pendp_desc
->bmAttributes
& USB_ENDPOINT_XFERTYPE_MASK
) == USB_ENDPOINT_XFER_BULK
)
1639 if (pendp_desc
->bEndpointAddress
& USB_DIR_IN
)
1641 pdev_ext
->pin_endp_desc
= pendp_desc
;
1642 pdev_ext
->in_endp_idx
= (UCHAR
) i
;
1646 pdev_ext
->pout_endp_desc
= pendp_desc
;
1647 pdev_ext
->out_endp_idx
= (UCHAR
) i
;
1650 pendp_desc
= &pendp_desc
[1];
1657 // notify the class driver, some device comes
1658 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdrvr
->driver_ext
;
1659 if (pdrvr_ext
&& pdrvr_ext
->class_driver_info
.add_device
&& pdrvr_ext
->class_driver_info
.fdo_driver
)
1660 pdrvr_ext
->class_driver_info
.add_device(pdrvr_ext
->class_driver_info
.fdo_driver
, pdev_obj
);
1662 usb_unlock_dev(pdev
);
1667 usb_free_mem(desc_buf
);
1672 usb_unlock_dev(pdev
);
1681 umss_if_disconnect(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE if_handle
)
1686 PUSB_DRIVER pdrvr
= NULL
;
1687 PDEVICE_OBJECT dev_obj
= NULL
;
1688 PUMSS_DRVR_EXTENSION pdrvr_ext
;
1689 PUMSS_DEVICE_EXTENSION pdev_ext
;
1691 if (dev_mgr
== NULL
|| if_handle
== 0)
1695 if_idx
= if_idx_from_handle(if_handle
);
1697 // special use of the lock dev, simply use this routine to get the dev
1699 status
= usb_query_and_lock_dev(dev_mgr
, if_handle
, &pdev
);
1704 if (status
== STATUS_SUCCESS
)
1709 if (pdev
->usb_config
)
1711 pdrvr
= pdev
->usb_config
->interf
[if_idx
].pif_drv
;
1712 dev_obj
= (PDEVICE_OBJECT
) pdev
->usb_config
->interf
[if_idx
].if_ext
;
1716 // notify the class driver, some device gone
1717 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdrvr
->driver_ext
;
1718 pdev_ext
= dev_obj
->DeviceExtension
;
1719 if (pdrvr_ext
&& pdrvr_ext
->class_driver_info
.pnp_dispatch
)
1720 pdrvr_ext
->class_driver_info
.pnp_dispatch(dev_obj
, UMSS_PNPMSG_DISCONNECT
, NULL
);
1722 // no need to unlock the dev
1723 return umss_delete_device(dev_mgr
, pdrvr
, dev_obj
, TRUE
);
1727 umss_if_stop(PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE if_handle
)
1732 PUSB_DRIVER pdrvr
= NULL
;
1733 PDEVICE_OBJECT dev_obj
= NULL
;
1734 PUMSS_DRVR_EXTENSION pdrvr_ext
;
1735 PUMSS_DEVICE_EXTENSION pdev_ext
;
1736 USE_BASIC_NON_PENDING_IRQL
;
1738 if (dev_mgr
== NULL
|| if_handle
== 0)
1742 if_idx
= if_idx_from_handle(if_handle
);
1744 // special use of the lock dev, simply use this routine to get the dev
1745 status
= usb_query_and_lock_dev(dev_mgr
, if_handle
, &pdev
);
1746 if (status
!= STATUS_SUCCESS
)
1751 lock_dev(pdev
, FALSE
);
1752 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1757 if (pdev
->usb_config
)
1759 pdrvr
= pdev
->usb_config
->interf
[if_idx
].pif_drv
;
1760 dev_obj
= (PDEVICE_OBJECT
) pdev
->usb_config
->interf
[if_idx
].if_ext
;
1762 unlock_dev(pdev
, FALSE
);
1764 // notify the class driver, some device stops
1765 pdev_ext
= dev_obj
->DeviceExtension
;
1766 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdrvr
->driver_ext
;
1767 if (pdrvr_ext
&& pdrvr_ext
->class_driver_info
.pnp_dispatch
)
1768 pdrvr_ext
->class_driver_info
.pnp_dispatch(dev_obj
, UMSS_PNPMSG_STOP
, NULL
);
1770 usb_unlock_dev(pdev
);
1775 umss_load_class_driver(PVOID context
)
1778 UNICODE_STRING unicode_string
;
1780 UNREFERENCED_PARAMETER(context
);
1783 // let's load the class driver
1785 RtlInitUnicodeString(&unicode_string
,
1786 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\usbstor");
1787 status
= ZwLoadDriver(&unicode_string
);
1788 usb_dbg_print(DBGLVL_MAXIMUM
,
1789 ("umss_load_class_driver(): try to load class driver, status=0x%x\n", status
));
1793 umss_if_driver_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
)
1795 PUMSS_DRVR_EXTENSION pdrvr_ext
;
1797 if (dev_mgr
== NULL
|| pdriver
== NULL
)
1800 //init driver structure, no PNP table functions
1802 pdriver
->driver_desc
.flags
= USB_DRIVER_FLAG_IF_CAPABLE
;
1803 pdriver
->driver_desc
.vendor_id
= 0x0000; // USB Vendor ID
1804 pdriver
->driver_desc
.product_id
= 0x0000; // USB Product ID.
1805 pdriver
->driver_desc
.release_num
= 0x100; // Release Number of Device
1807 pdriver
->driver_desc
.config_val
= 1; // Configuration Value
1808 pdriver
->driver_desc
.if_num
= 1; // Interface Number
1809 pdriver
->driver_desc
.if_class
= USB_CLASS_MASS_STORAGE
; // Interface Class
1810 pdriver
->driver_desc
.if_sub_class
= 0; // Interface SubClass
1811 pdriver
->driver_desc
.if_protocol
= 0; // Interface Protocol
1813 pdriver
->driver_desc
.driver_name
= "USB Mass Storage interface driver"; // Driver name for Name Registry
1814 pdriver
->driver_desc
.dev_class
= USB_CLASS_PER_INTERFACE
;
1815 pdriver
->driver_desc
.dev_sub_class
= 0; // Device Subclass
1816 pdriver
->driver_desc
.dev_protocol
= 0; // Protocol Info.
1818 pdriver
->driver_ext
= usb_alloc_mem(NonPagedPool
, sizeof(UMSS_DRVR_EXTENSION
));
1819 if (!pdriver
->driver_ext
) return FALSE
;
1821 pdriver
->driver_ext_size
= sizeof(UMSS_DRVR_EXTENSION
);
1823 RtlZeroMemory(pdriver
->driver_ext
, sizeof(UMSS_DRVR_EXTENSION
));
1825 pdrvr_ext
= (PUMSS_DRVR_EXTENSION
) pdriver
->driver_ext
;
1826 pdrvr_ext
->dev_count
= 0;
1827 InitializeListHead(&pdrvr_ext
->dev_list
);
1828 ExInitializeFastMutex(&pdrvr_ext
->dev_list_mutex
);
1830 pdriver
->disp_tbl
.version
= 1;
1831 pdriver
->disp_tbl
.dev_connect
= umss_if_connect
;
1832 pdriver
->disp_tbl
.dev_disconnect
= umss_if_disconnect
;
1833 pdriver
->disp_tbl
.dev_stop
= umss_if_stop
;
1834 pdriver
->disp_tbl
.dev_reserved
= NULL
;
1836 if ((pdrvr_ext
->port_dev_obj
= umss_create_port_device(dev_mgr
, pdriver
)) == NULL
)
1838 usb_free_mem(pdriver
->driver_ext
);
1839 pdriver
->driver_ext
= NULL
;
1840 pdriver
->driver_ext_size
= 0;
1841 pdriver
->disp_tbl
.dev_connect
= NULL
;
1842 pdriver
->disp_tbl
.dev_stop
= NULL
;
1843 pdriver
->disp_tbl
.dev_disconnect
= NULL
;
1848 // let's load the class driver
1850 umss_load_class_driver(NULL
);
1852 // umss_schedule_workitem( NULL, umss_load_class_driver, NULL, 0 );
1853 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_if_driver_init(): umss driver is initialized\n"));
1858 // get the driver reg information for pnp notification to class
1860 // bug??? how if the driver info is returned while the driver
1861 // is being unloaded.
1862 // So the routine must be called when usb_query_and_lock_dev is
1865 umss_get_if_driver_info(PUSB_DEV_MANAGER dev_mgr
, PUSB_DEV pdev
, DEV_HANDLE if_handle
)
1867 PUMSS_DRVR_EXTENSION drvr_ext
;
1869 USE_BASIC_NON_PENDING_IRQL
;
1871 UNREFERENCED_PARAMETER(dev_mgr
);
1873 if_idx
= if_idx_from_handle(if_handle
);
1874 if (if_idx
>= 4) // max interfaces per config supports. defined in td.h
1877 ASSERT(pdev
!= NULL
);
1879 lock_dev(pdev
, FALSE
);
1880 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1882 unlock_dev(pdev
, FALSE
);
1883 usb_unlock_dev(pdev
);
1889 if (pdev
->usb_config
->interf
[if_idx
].pif_drv
)
1890 drvr_ext
= (PUMSS_DRVR_EXTENSION
) pdev
->usb_config
->interf
[if_idx
].pif_drv
->driver_ext
;
1894 unlock_dev(pdev
, FALSE
);
1896 if (drvr_ext
== NULL
)
1901 return &drvr_ext
->class_driver_info
;
1905 umss_worker(IN PVOID reference
)
1907 PUMSS_WORKER_PACKET worker_packet
;
1910 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_worker(): entering...\n"));
1911 worker_packet
= (PUMSS_WORKER_PACKET
) reference
;
1912 worker_packet
->completion(worker_packet
->context
);
1913 if (worker_packet
->dev_mgr
&& worker_packet
->pdev
)
1915 pdev
= (PUSB_DEV
) worker_packet
->pdev
;
1916 usb_unlock_dev(pdev
);
1919 usb_free_mem(worker_packet
);
1920 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_worker(): exit\n"));
1924 Routine Description:
1926 Wrapper for handling worker thread callbacks, it is importent to
1927 lock the dev from being deleted by calling usb_query_and_lock_dev
1928 and in umss_worker, call the usb_unlock_dev to release the ref
1929 count. One exception is that the umss_if_disconnect call this
1930 function to delete the device object that is still held by some
1931 others, and deferred deletion is required.
1935 Routine - Routine to be called when this work-item is processed
1936 Context - Value to be passed to worker routine
1939 TRUE if work item queued
1940 FALSE if work item not queued
1944 umss_schedule_workitem(PVOID context
,
1945 UMSS_WORKER_ROUTINE completion
, PUSB_DEV_MANAGER dev_mgr
, DEV_HANDLE dev_handle
)
1947 BOOLEAN ret_val
= TRUE
;
1948 PWORK_QUEUE_ITEM workitem
;
1949 PUMSS_WORKER_PACKET worker_packet
;
1951 worker_packet
= usb_alloc_mem(NonPagedPool
, sizeof(WORK_QUEUE_ITEM
) + sizeof(UMSS_WORKER_PACKET
));
1955 RtlZeroMemory(worker_packet
, sizeof(WORK_QUEUE_ITEM
) + sizeof(UMSS_WORKER_PACKET
));
1957 workitem
= (PWORK_QUEUE_ITEM
) & worker_packet
[1];
1958 worker_packet
->completion
= completion
;
1959 worker_packet
->context
= context
;
1961 if (dev_mgr
!= NULL
&& dev_handle
!= 0)
1964 // lock the device until the workitem is executed.
1965 if (usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
) == STATUS_SUCCESS
)
1967 worker_packet
->dev_mgr
= dev_mgr
;
1968 worker_packet
->pdev
= pdev
;
1972 usb_free_mem(worker_packet
);
1976 // Initialize the work-item
1977 ExInitializeWorkItem(workitem
, umss_worker
, worker_packet
);
1979 // Schedule the work-item
1980 ExQueueWorkItem(workitem
, DelayedWorkQueue
);
1982 usb_dbg_print(DBGLVL_MINIMUM
, ("umss_schedule_workitem(): work-item queued\n"));
1986 usb_dbg_print(DBGLVL_MINIMUM
, ("umss_schedule_workitem(): Failed to allocate work-item\n"));
1994 umss_process_srb(PDEVICE_OBJECT dev_obj
, PIRP irp
)
1998 PIO_STACK_LOCATION cur_stack
;
1999 PUMSS_DEVICE_EXTENSION pdev_ext
;
2000 PSCSI_REQUEST_BLOCK srb
;
2002 if (dev_obj
== NULL
|| irp
== NULL
)
2003 return STATUS_INVALID_PARAMETER
;
2006 cur_stack
= IoGetCurrentIrpStackLocation(irp
);
2007 srb
= cur_stack
->Parameters
.Scsi
.Srb
;
2009 if (srb
== NULL
|| srb
->DataTransferLength
> 65536)
2011 status
= STATUS_INVALID_PARAMETER
;
2015 irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2016 irp
->IoStatus
.Information
= 0;
2018 pdev_ext
= (PUMSS_DEVICE_EXTENSION
) dev_obj
->DeviceExtension
;
2019 if ((status
= usb_query_and_lock_dev(pdev_ext
->dev_mgr
, pdev_ext
->dev_handle
, &pdev
)) != STATUS_SUCCESS
)
2021 PSENSE_DATA sense_buf
;
2022 srb
->SrbStatus
= SRB_STATUS_NO_DEVICE
;
2025 // let's build the srb status for class driver
2027 srb
->SrbStatus
|= SRB_STATUS_AUTOSENSE_VALID
;
2028 RtlZeroMemory(srb
->SenseInfoBuffer
, srb
->SenseInfoBufferLength
);
2029 if (!(srb
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
))
2031 sense_buf
= (PSENSE_DATA
) srb
->SenseInfoBuffer
;
2032 sense_buf
->ErrorCode
= 0x70;
2033 sense_buf
->Valid
= 1;
2034 sense_buf
->SenseKey
= SCSI_SENSE_NOT_READY
;
2035 sense_buf
->AdditionalSenseCode
= SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
;
2036 sense_buf
->AdditionalSenseLength
= 10;
2041 switch (srb
->Function
)
2043 case SRB_FUNCTION_EXECUTE_SCSI
:
2045 IO_PACKET io_packet
;
2046 RtlZeroMemory(&io_packet
, sizeof(io_packet
));
2048 io_packet
.flags
|= IOP_FLAG_SRB_TRANSFER
;
2049 if (srb
->SrbFlags
& SRB_FLAGS_DATA_IN
)
2050 io_packet
.flags
|= IOP_FLAG_DIR_IN
;
2051 if (!(srb
->SrbFlags
& SRB_FLAGS_DISABLE_AUTOSENSE
))
2052 io_packet
.flags
|= IOP_FLAG_REQ_SENSE
;
2054 io_packet
.cdb_length
= srb
->CdbLength
;
2055 RtlCopyMemory(io_packet
.cdb
, srb
->Cdb
, sizeof(io_packet
.cdb
));
2058 if (srb
->SrbFlags
& SRB_FLAGS_NO_DATA_TRANSFER
)
2060 io_packet
.data_buffer
= NULL
;
2061 io_packet
.data_length
= 0;
2065 if ((irp
->Flags
& (IRP_READ_OPERATION
| IRP_WRITE_OPERATION
))
2066 && !(irp
->Flags
& IRP_PAGING_IO
))
2069 // since these operations does not allign the buffer on page boundary
2070 // and some unknown traps in window NT, we have to copy to a buffer
2072 io_packet
.data_buffer
= usb_alloc_mem(NonPagedPool
, srb
->DataTransferLength
);
2073 if (irp
->Flags
& IRP_WRITE_OPERATION
)
2075 PULONG dest_buf
, src_buf
;
2078 dest_buf
= (PULONG
) io_packet
.data_buffer
;
2079 src_buf
= (PULONG
) srb
->DataBuffer
;
2081 if (src_buf
&& dest_buf
)
2083 for(i
= 0; i
< (srb
->DataTransferLength
>> 2); i
++)
2085 dest_buf
[i
] = src_buf
[i
];
2091 io_packet
.data_buffer
= srb
->DataBuffer
;
2093 io_packet
.data_length
= srb
->DataTransferLength
;
2096 if (io_packet
.flags
& IOP_FLAG_REQ_SENSE
)
2098 io_packet
.sense_data
= srb
->SenseInfoBuffer
;
2099 io_packet
.sense_data_length
= srb
->SenseInfoBufferLength
;
2102 io_packet
.pirp
= irp
;
2104 // do some conversions
2105 if (pdev_ext
->pif_desc
->bInterfaceSubClass
== UMSS_SUBCLASS_SFF8070I
)
2107 if (umss_tsc_to_sff(&io_packet
) == FALSE
)
2109 status
= STATUS_DEVICE_PROTOCOL_ERROR
;
2111 usb_dbg_print(DBGLVL_MAXIMUM
,
2112 ("umss_process_srb(): error converting to sff proto, 0x%x\n", status
));
2113 srb
->SrbStatus
= SRB_STATUS_ERROR
;
2118 if (pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_BULKONLY
)
2121 // currently we support only transparent scsi command set
2123 if (pdev_ext
->pif_desc
->bInterfaceSubClass
== UMSS_SUBCLASS_SCSI_TCS
||
2124 pdev_ext
->pif_desc
->bInterfaceSubClass
== UMSS_SUBCLASS_SFF8070I
)
2125 status
= umss_bulkonly_startio(pdev_ext
, &io_packet
);
2127 status
= STATUS_DEVICE_PROTOCOL_ERROR
;
2129 else if (pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_CB
2130 || pdev_ext
->pif_desc
->bInterfaceProtocol
== PROTOCOL_CBI
)
2132 status
= umss_cbi_startio(pdev_ext
, &io_packet
);
2136 status
= STATUS_DEVICE_PROTOCOL_ERROR
;
2139 if (status
!= STATUS_PENDING
&& status
!= STATUS_SUCCESS
)
2142 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_process_srb(): error sending request, 0x%x\n", status
));
2143 srb
->SrbStatus
= SRB_STATUS_ERROR
;
2147 case SRB_FUNCTION_CLAIM_DEVICE
:
2149 srb
->DataBuffer
= (PVOID
) dev_obj
;
2151 case SRB_FUNCTION_SHUTDOWN
:
2152 case SRB_FUNCTION_FLUSH
:
2153 case SRB_FUNCTION_RESET_BUS
:
2154 case SRB_FUNCTION_FLUSH_QUEUE
:
2155 case SRB_FUNCTION_RELEASE_QUEUE
:
2156 case SRB_FUNCTION_RELEASE_DEVICE
:
2159 // for usb flash disk, they are luxurious
2161 usb_dbg_print(DBGLVL_MAXIMUM
, ("umss_process_srb(): current srb->Function=0x%x\n",
2164 status
= STATUS_SUCCESS
;
2165 srb
->SrbStatus
= SRB_STATUS_SUCCESS
;
2170 usb_unlock_dev(pdev
);
2174 irp
->IoStatus
.Status
= status
;
2175 if (status
!= STATUS_PENDING
)
2177 IoStartNextPacket(dev_obj
, FALSE
);
2178 IoCompleteRequest(irp
, IO_NO_INCREMENT
);
2182 // UMSS_COMPLETE_START_IO( dev_obj, status, irp );
2188 umss_tsc_to_sff(PIO_PACKET io_packet
)
2190 if (io_packet
== NULL
)
2193 io_packet
->cdb_length
= 12;
2194 if (io_packet
->cdb
[0] == SCSIOP_MODE_SENSE
)
2196 io_packet
->cdb
[0] = 0x5a; // mode sense( 10 )
2197 io_packet
->cdb
[8] = io_packet
->cdb
[4];
2198 io_packet
->cdb
[4] = 0;
2199 if (io_packet
->cdb
[8] < 8)
2200 io_packet
->cdb
[8] = 8;
2202 io_packet
->data_length
= 8;
2205 if (io_packet
->cdb
[0] == SCSIOP_REASSIGN_BLOCKS
||
2206 io_packet
->cdb
[0] == SCSIOP_RESERVE_UNIT
|| io_packet
->cdb
[0] == SCSIOP_RELEASE_UNIT
)
2213 umss_fix_sff_result(PIO_PACKET io_packet
, SCSI_REQUEST_BLOCK
*srb
)
2216 if (io_packet
->cdb
[0] != 0x5a)
2218 // the following is not right since it has to be 0x3f, return all pages
2219 // if( io_packet->cdb[ 2 ] != 0 )
2221 srb
->DataTransferLength
= 4;
2222 buf
= io_packet
->data_buffer
;
2223 // convert the mode param to scsi II