xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/newhost/drvUSBDisk.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1*53ee8cc1Swenshuai.xi //<MStar Software>
2*53ee8cc1Swenshuai.xi //******************************************************************************
3*53ee8cc1Swenshuai.xi // MStar Software
4*53ee8cc1Swenshuai.xi // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5*53ee8cc1Swenshuai.xi // All software, firmware and related documentation herein ("MStar Software") are
6*53ee8cc1Swenshuai.xi // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7*53ee8cc1Swenshuai.xi // law, including, but not limited to, copyright law and international treaties.
8*53ee8cc1Swenshuai.xi // Any use, modification, reproduction, retransmission, or republication of all
9*53ee8cc1Swenshuai.xi // or part of MStar Software is expressly prohibited, unless prior written
10*53ee8cc1Swenshuai.xi // permission has been granted by MStar.
11*53ee8cc1Swenshuai.xi //
12*53ee8cc1Swenshuai.xi // By accessing, browsing and/or using MStar Software, you acknowledge that you
13*53ee8cc1Swenshuai.xi // have read, understood, and agree, to be bound by below terms ("Terms") and to
14*53ee8cc1Swenshuai.xi // comply with all applicable laws and regulations:
15*53ee8cc1Swenshuai.xi //
16*53ee8cc1Swenshuai.xi // 1. MStar shall retain any and all right, ownership and interest to MStar
17*53ee8cc1Swenshuai.xi //    Software and any modification/derivatives thereof.
18*53ee8cc1Swenshuai.xi //    No right, ownership, or interest to MStar Software and any
19*53ee8cc1Swenshuai.xi //    modification/derivatives thereof is transferred to you under Terms.
20*53ee8cc1Swenshuai.xi //
21*53ee8cc1Swenshuai.xi // 2. You understand that MStar Software might include, incorporate or be
22*53ee8cc1Swenshuai.xi //    supplied together with third party`s software and the use of MStar
23*53ee8cc1Swenshuai.xi //    Software may require additional licenses from third parties.
24*53ee8cc1Swenshuai.xi //    Therefore, you hereby agree it is your sole responsibility to separately
25*53ee8cc1Swenshuai.xi //    obtain any and all third party right and license necessary for your use of
26*53ee8cc1Swenshuai.xi //    such third party`s software.
27*53ee8cc1Swenshuai.xi //
28*53ee8cc1Swenshuai.xi // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29*53ee8cc1Swenshuai.xi //    MStar`s confidential information and you agree to keep MStar`s
30*53ee8cc1Swenshuai.xi //    confidential information in strictest confidence and not disclose to any
31*53ee8cc1Swenshuai.xi //    third party.
32*53ee8cc1Swenshuai.xi //
33*53ee8cc1Swenshuai.xi // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34*53ee8cc1Swenshuai.xi //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35*53ee8cc1Swenshuai.xi //    without limitation, any warranties of merchantability, non-infringement of
36*53ee8cc1Swenshuai.xi //    intellectual property rights, fitness for a particular purpose, error free
37*53ee8cc1Swenshuai.xi //    and in conformity with any international standard.  You agree to waive any
38*53ee8cc1Swenshuai.xi //    claim against MStar for any loss, damage, cost or expense that you may
39*53ee8cc1Swenshuai.xi //    incur related to your use of MStar Software.
40*53ee8cc1Swenshuai.xi //    In no event shall MStar be liable for any direct, indirect, incidental or
41*53ee8cc1Swenshuai.xi //    consequential damages, including without limitation, lost of profit or
42*53ee8cc1Swenshuai.xi //    revenues, lost or damage of data, and unauthorized system use.
43*53ee8cc1Swenshuai.xi //    You agree that this Section 4 shall still apply without being affected
44*53ee8cc1Swenshuai.xi //    even if MStar Software has been modified by MStar in accordance with your
45*53ee8cc1Swenshuai.xi //    request or instruction for your use, except otherwise agreed by both
46*53ee8cc1Swenshuai.xi //    parties in writing.
47*53ee8cc1Swenshuai.xi //
48*53ee8cc1Swenshuai.xi // 5. If requested, MStar may from time to time provide technical supports or
49*53ee8cc1Swenshuai.xi //    services in relation with MStar Software to you for your use of
50*53ee8cc1Swenshuai.xi //    MStar Software in conjunction with your or your customer`s product
51*53ee8cc1Swenshuai.xi //    ("Services").
52*53ee8cc1Swenshuai.xi //    You understand and agree that, except otherwise agreed by both parties in
53*53ee8cc1Swenshuai.xi //    writing, Services are provided on an "AS IS" basis and the warranty
54*53ee8cc1Swenshuai.xi //    disclaimer set forth in Section 4 above shall apply.
55*53ee8cc1Swenshuai.xi //
56*53ee8cc1Swenshuai.xi // 6. Nothing contained herein shall be construed as by implication, estoppels
57*53ee8cc1Swenshuai.xi //    or otherwise:
58*53ee8cc1Swenshuai.xi //    (a) conferring any license or right to use MStar name, trademark, service
59*53ee8cc1Swenshuai.xi //        mark, symbol or any other identification;
60*53ee8cc1Swenshuai.xi //    (b) obligating MStar or any of its affiliates to furnish any person,
61*53ee8cc1Swenshuai.xi //        including without limitation, you and your customers, any assistance
62*53ee8cc1Swenshuai.xi //        of any kind whatsoever, or any information; or
63*53ee8cc1Swenshuai.xi //    (c) conferring any license or right under any intellectual property right.
64*53ee8cc1Swenshuai.xi //
65*53ee8cc1Swenshuai.xi // 7. These terms shall be governed by and construed in accordance with the laws
66*53ee8cc1Swenshuai.xi //    of Taiwan, R.O.C., excluding its conflict of law rules.
67*53ee8cc1Swenshuai.xi //    Any and all dispute arising out hereof or related hereto shall be finally
68*53ee8cc1Swenshuai.xi //    settled by arbitration referred to the Chinese Arbitration Association,
69*53ee8cc1Swenshuai.xi //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70*53ee8cc1Swenshuai.xi //    Rules of the Association by three (3) arbitrators appointed in accordance
71*53ee8cc1Swenshuai.xi //    with the said Rules.
72*53ee8cc1Swenshuai.xi //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73*53ee8cc1Swenshuai.xi //    be English.
74*53ee8cc1Swenshuai.xi //    The arbitration award shall be final and binding to both parties.
75*53ee8cc1Swenshuai.xi //
76*53ee8cc1Swenshuai.xi //******************************************************************************
77*53ee8cc1Swenshuai.xi //<MStar Software>
78*53ee8cc1Swenshuai.xi 
79*53ee8cc1Swenshuai.xi //#include <cyg/infra/cyg_type.h> // NUSED
80*53ee8cc1Swenshuai.xi //#include <cyg/infra/cyg_ass.h> // NUSED
81*53ee8cc1Swenshuai.xi //#include <cyg/infra/diag.h>  // NUSED
82*53ee8cc1Swenshuai.xi //#include <cyg/hal/hal_arch.h>  // NUSED
83*53ee8cc1Swenshuai.xi //#include <cyg/hal/hal_io.h> // NUSED
84*53ee8cc1Swenshuai.xi //#include <cyg/hal/drv_api.h> // NUSED
85*53ee8cc1Swenshuai.xi //#include <cyg/io/io.h> // NUSED
86*53ee8cc1Swenshuai.xi //#include <cyg/io/devtab.h> // NUSED
87*53ee8cc1Swenshuai.xi #include <cyg/io/disk.h>
88*53ee8cc1Swenshuai.xi 
89*53ee8cc1Swenshuai.xi //#include "drvMSC.h" // NUSED
90*53ee8cc1Swenshuai.xi #include "drvMassStor.h"
91*53ee8cc1Swenshuai.xi //#include "drvUSB.h" // NUSED
92*53ee8cc1Swenshuai.xi /* applying drvUsbHostConfig.h (inside drvMassStor.h) */
93*53ee8cc1Swenshuai.xi 
94*53ee8cc1Swenshuai.xi //#define _USB_DISK_DEBUG	1
95*53ee8cc1Swenshuai.xi 
96*53ee8cc1Swenshuai.xi typedef struct {
97*53ee8cc1Swenshuai.xi     int         uLunNum;
98*53ee8cc1Swenshuai.xi     cyg_uint32  size;
99*53ee8cc1Swenshuai.xi     int         uPort;
100*53ee8cc1Swenshuai.xi     int         DevId;
101*53ee8cc1Swenshuai.xi } usb_disk_info_t;
102*53ee8cc1Swenshuai.xi 
103*53ee8cc1Swenshuai.xi // ----------------------------------------------------------------------------
104*53ee8cc1Swenshuai.xi #ifndef __lint__ //NOTE: lint will complain for the following device tables..
105*53ee8cc1Swenshuai.xi static bool usb_disk_init(struct cyg_devtab_entry *tab);
106*53ee8cc1Swenshuai.xi 
107*53ee8cc1Swenshuai.xi static Cyg_ErrNo usb_disk_read(disk_channel *chan,
108*53ee8cc1Swenshuai.xi                                  void         *buf,
109*53ee8cc1Swenshuai.xi                                  cyg_uint32    len,
110*53ee8cc1Swenshuai.xi                                  cyg_uint32    block_num);
111*53ee8cc1Swenshuai.xi 
112*53ee8cc1Swenshuai.xi static Cyg_ErrNo usb_disk_write(disk_channel *chan,
113*53ee8cc1Swenshuai.xi                                   const void   *buf,
114*53ee8cc1Swenshuai.xi                                   cyg_uint32    len,
115*53ee8cc1Swenshuai.xi                                   cyg_uint32    block_num);
116*53ee8cc1Swenshuai.xi 
117*53ee8cc1Swenshuai.xi static Cyg_ErrNo usb_disk_get_config(disk_channel *chan,
118*53ee8cc1Swenshuai.xi                                        cyg_uint32    key,
119*53ee8cc1Swenshuai.xi                                        const void   *xbuf,
120*53ee8cc1Swenshuai.xi                                        cyg_uint32   *len);
121*53ee8cc1Swenshuai.xi 
122*53ee8cc1Swenshuai.xi static Cyg_ErrNo usb_disk_set_config(disk_channel *chan,
123*53ee8cc1Swenshuai.xi                                        cyg_uint32    key,
124*53ee8cc1Swenshuai.xi                                        const void   *xbuf,
125*53ee8cc1Swenshuai.xi                                        cyg_uint32   *len);
126*53ee8cc1Swenshuai.xi 
127*53ee8cc1Swenshuai.xi static Cyg_ErrNo usb_disk_lookup(struct cyg_devtab_entry  **tab,
128*53ee8cc1Swenshuai.xi                                    struct cyg_devtab_entry   *sub_tab,
129*53ee8cc1Swenshuai.xi                                    const char                *name);
130*53ee8cc1Swenshuai.xi 
131*53ee8cc1Swenshuai.xi static struct DISK_FUNS(usb_disk_funs,
132*53ee8cc1Swenshuai.xi                  &usb_disk_read,
133*53ee8cc1Swenshuai.xi                  &usb_disk_write,
134*53ee8cc1Swenshuai.xi                  &usb_disk_get_config,
135*53ee8cc1Swenshuai.xi                  &usb_disk_set_config
136*53ee8cc1Swenshuai.xi );
137*53ee8cc1Swenshuai.xi 
138*53ee8cc1Swenshuai.xi // We define 10 empty block device entries for our USB storage device.
139*53ee8cc1Swenshuai.xi // Initially, these entries can not be used until the USB module connect it.
140*53ee8cc1Swenshuai.xi #if 1
141*53ee8cc1Swenshuai.xi #define USB_DISK_INSTANCE(_number_,_port_,_name_)        \
142*53ee8cc1Swenshuai.xi     static usb_disk_info_t usb_disk_info##_port_##_number_ = {         \
143*53ee8cc1Swenshuai.xi         -1,                                   \
144*53ee8cc1Swenshuai.xi         0,                                    \
145*53ee8cc1Swenshuai.xi         -1,                                   \
146*53ee8cc1Swenshuai.xi         -1                                    \
147*53ee8cc1Swenshuai.xi     };                            \
148*53ee8cc1Swenshuai.xi     disk_controller usb_disk_controller##_port_##_number_ = {          \
149*53ee8cc1Swenshuai.xi     priv:       NULL,                         \
150*53ee8cc1Swenshuai.xi     init:       false,                          \
151*53ee8cc1Swenshuai.xi     busy:       false                           \
152*53ee8cc1Swenshuai.xi     };                      \
153*53ee8cc1Swenshuai.xi     DISK_CHANNEL(usb_disk_channel##_port_##_number_,     \
154*53ee8cc1Swenshuai.xi     usb_disk_funs,                                             \
155*53ee8cc1Swenshuai.xi     usb_disk_info##_port_##_number_,                          \
156*53ee8cc1Swenshuai.xi     usb_disk_controller##_port_##_number_,                   \
157*53ee8cc1Swenshuai.xi     true           \
158*53ee8cc1Swenshuai.xi     );                             \
159*53ee8cc1Swenshuai.xi     BLOCK_DEVTAB_ENTRY(usb_disk_io##_port_##_number_, \
160*53ee8cc1Swenshuai.xi     _name_,                                              \
161*53ee8cc1Swenshuai.xi     0,                                                   \
162*53ee8cc1Swenshuai.xi     &cyg_io_disk_devio,                      \
163*53ee8cc1Swenshuai.xi     &usb_disk_init,                                \
164*53ee8cc1Swenshuai.xi     &usb_disk_lookup,                           \
165*53ee8cc1Swenshuai.xi     &usb_disk_channel##_port_##_number_              \
166*53ee8cc1Swenshuai.xi     );
167*53ee8cc1Swenshuai.xi #else
168*53ee8cc1Swenshuai.xi #define USB_DISK_INSTANCE(_number_,_port_,_name_)        \
169*53ee8cc1Swenshuai.xi     static usb_disk_info_t usb_disk_info##_port_##_number_ = {         \
170*53ee8cc1Swenshuai.xi     num: _number_,                                   \
171*53ee8cc1Swenshuai.xi     size: 0,                                         \
172*53ee8cc1Swenshuai.xi     uPort: _port_ ,                                   \
173*53ee8cc1Swenshuai.xi     DevId: -1                                        \
174*53ee8cc1Swenshuai.xi     };                            \
175*53ee8cc1Swenshuai.xi     disk_controller usb_disk_controller##_port_##_number_ = {          \
176*53ee8cc1Swenshuai.xi     priv:       NULL,                         \
177*53ee8cc1Swenshuai.xi     init:       false,                          \
178*53ee8cc1Swenshuai.xi     busy:       false                           \
179*53ee8cc1Swenshuai.xi     };                      \
180*53ee8cc1Swenshuai.xi     DISK_CHANNEL(usb_disk_channel##_port_##_number_,     \
181*53ee8cc1Swenshuai.xi     usb_disk_funs,                                             \
182*53ee8cc1Swenshuai.xi     usb_disk_info##_port_##_number_,                          \
183*53ee8cc1Swenshuai.xi     usb_disk_controller##_port_##_number_,                   \
184*53ee8cc1Swenshuai.xi     true           \
185*53ee8cc1Swenshuai.xi     );                             \
186*53ee8cc1Swenshuai.xi     BLOCK_DEVTAB_ENTRY(usb_disk_io##_port_##_number_, \
187*53ee8cc1Swenshuai.xi     _name_,                                              \
188*53ee8cc1Swenshuai.xi     0,                                                   \
189*53ee8cc1Swenshuai.xi     &cyg_io_disk_devio,                      \
190*53ee8cc1Swenshuai.xi     &usb_disk_init,                                \
191*53ee8cc1Swenshuai.xi     &usb_disk_lookup,                           \
192*53ee8cc1Swenshuai.xi     &usb_disk_channel##_port_##_number_              \
193*53ee8cc1Swenshuai.xi     );
194*53ee8cc1Swenshuai.xi #endif
195*53ee8cc1Swenshuai.xi 
196*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(0, 0, "/dev/sda/");
197*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(1, 0, "/dev/sdb/");
198*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(2, 0, "/dev/sdc/");
199*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(3, 0, "/dev/sdd/");
200*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(4, 0, "/dev/sde/");
201*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(5, 0, "/dev/sdf/");
202*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(6, 0, "/dev/sdg/");
203*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(7, 0, "/dev/sdh/");
204*53ee8cc1Swenshuai.xi 
205*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(0, 1, "/dev/sdi/");
206*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(1, 1, "/dev/sdj/");
207*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(2, 1, "/dev/sdk/");
208*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(3, 1, "/dev/sdl/");
209*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(4, 1, "/dev/sdm/");
210*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(5, 1, "/dev/sdn/");
211*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(6, 1, "/dev/sdo/");
212*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(7, 1, "/dev/sdp/");
213*53ee8cc1Swenshuai.xi 
214*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(0, 2, "/dev/sdq/");
215*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(1, 2, "/dev/sdr/");
216*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(2, 2, "/dev/sds/");
217*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(3, 2, "/dev/sdt/");
218*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(4, 2, "/dev/sdu/");
219*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(5, 2, "/dev/sdv/");
220*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(6, 2, "/dev/sdw/");
221*53ee8cc1Swenshuai.xi USB_DISK_INSTANCE(7, 2, "/dev/sdx/");
222*53ee8cc1Swenshuai.xi 
223*53ee8cc1Swenshuai.xi #define USBBLOCK_DEVNAME    "/dev/sd"
is_usb_block_dev(cyg_devtab_entry_t * t)224*53ee8cc1Swenshuai.xi static BOOL is_usb_block_dev(cyg_devtab_entry_t *t)
225*53ee8cc1Swenshuai.xi {
226*53ee8cc1Swenshuai.xi     return (strncmp(t->name, USBBLOCK_DEVNAME,
227*53ee8cc1Swenshuai.xi         sizeof(USBBLOCK_DEVNAME)-1) == 0 ? TRUE: FALSE);
228*53ee8cc1Swenshuai.xi }
229*53ee8cc1Swenshuai.xi 
230*53ee8cc1Swenshuai.xi #ifdef _USB_DISK_DEBUG
dump_data(cyg_uint8 * buf,cyg_uint32 len)231*53ee8cc1Swenshuai.xi void dump_data(cyg_uint8 *buf, cyg_uint32 len)
232*53ee8cc1Swenshuai.xi {
233*53ee8cc1Swenshuai.xi     int i, j=0;
234*53ee8cc1Swenshuai.xi 
235*53ee8cc1Swenshuai.xi     while(j<len)
236*53ee8cc1Swenshuai.xi     {
237*53ee8cc1Swenshuai.xi         diag_printf("[ ");
238*53ee8cc1Swenshuai.xi         for (i=0; i<16; i++)
239*53ee8cc1Swenshuai.xi             diag_printf("%x ", buf[j+i]);
240*53ee8cc1Swenshuai.xi         diag_printf(" ]\n");
241*53ee8cc1Swenshuai.xi         j+=i;
242*53ee8cc1Swenshuai.xi     }
243*53ee8cc1Swenshuai.xi 
244*53ee8cc1Swenshuai.xi }
245*53ee8cc1Swenshuai.xi #endif
246*53ee8cc1Swenshuai.xi 
247*53ee8cc1Swenshuai.xi static bool
usb_disk_init(struct cyg_devtab_entry * tab)248*53ee8cc1Swenshuai.xi usb_disk_init(struct cyg_devtab_entry *tab)
249*53ee8cc1Swenshuai.xi {
250*53ee8cc1Swenshuai.xi     disk_channel      *chan       = (disk_channel *) tab->priv;
251*53ee8cc1Swenshuai.xi     cyg_disk_info_t *info = chan->info;
252*53ee8cc1Swenshuai.xi 
253*53ee8cc1Swenshuai.xi     info->connected = false;
254*53ee8cc1Swenshuai.xi     chan->valid = false;
255*53ee8cc1Swenshuai.xi 
256*53ee8cc1Swenshuai.xi     if (chan->init)
257*53ee8cc1Swenshuai.xi         return true;
258*53ee8cc1Swenshuai.xi 
259*53ee8cc1Swenshuai.xi 
260*53ee8cc1Swenshuai.xi     //if (!(chan->callbacks->disk_init)(tab))
261*53ee8cc1Swenshuai.xi     //return false;
262*53ee8cc1Swenshuai.xi 
263*53ee8cc1Swenshuai.xi     // Initially, we declare that we are not connected
264*53ee8cc1Swenshuai.xi     info->connected = false;
265*53ee8cc1Swenshuai.xi     chan->valid     = false;
266*53ee8cc1Swenshuai.xi 
267*53ee8cc1Swenshuai.xi     return true;
268*53ee8cc1Swenshuai.xi }
269*53ee8cc1Swenshuai.xi 
270*53ee8cc1Swenshuai.xi static Cyg_ErrNo
usb_disk_lookup(struct cyg_devtab_entry ** tab,struct cyg_devtab_entry * sub_tab,const char * name)271*53ee8cc1Swenshuai.xi usb_disk_lookup(struct cyg_devtab_entry **tab,
272*53ee8cc1Swenshuai.xi                   struct cyg_devtab_entry  *sub_tab,
273*53ee8cc1Swenshuai.xi                   const char               *name)
274*53ee8cc1Swenshuai.xi {
275*53ee8cc1Swenshuai.xi     disk_channel *chan = (disk_channel *) (*tab)->priv;
276*53ee8cc1Swenshuai.xi     return (chan->callbacks->disk_lookup(tab, sub_tab, name));
277*53ee8cc1Swenshuai.xi }
278*53ee8cc1Swenshuai.xi 
279*53ee8cc1Swenshuai.xi static Cyg_ErrNo
usb_disk_read(disk_channel * chan,void * buf,cyg_uint32 len,cyg_uint32 block_num)280*53ee8cc1Swenshuai.xi usb_disk_read(disk_channel *chan,
281*53ee8cc1Swenshuai.xi                 void         *buf,
282*53ee8cc1Swenshuai.xi                 cyg_uint32    len,
283*53ee8cc1Swenshuai.xi                 cyg_uint32    block_num)
284*53ee8cc1Swenshuai.xi {
285*53ee8cc1Swenshuai.xi     usb_disk_info_t *usb_info = (usb_disk_info_t *)chan->dev_priv;
286*53ee8cc1Swenshuai.xi 
287*53ee8cc1Swenshuai.xi     if ((usb_info->uPort == -1) ||
288*53ee8cc1Swenshuai.xi         (usb_info->uLunNum == -1) ||
289*53ee8cc1Swenshuai.xi         (usb_info->DevId == -1) )
290*53ee8cc1Swenshuai.xi     {
291*53ee8cc1Swenshuai.xi         diag_printf("Err: usb_disk_read: device not exist \n");
292*53ee8cc1Swenshuai.xi         return ENODEV;
293*53ee8cc1Swenshuai.xi     }
294*53ee8cc1Swenshuai.xi 
295*53ee8cc1Swenshuai.xi     if (ms_bSCSI_Read_10(usb_info->uPort, usb_info->uLunNum, block_num,
296*53ee8cc1Swenshuai.xi         len , (cyg_uint8*)buf) )
297*53ee8cc1Swenshuai.xi     {
298*53ee8cc1Swenshuai.xi         #ifdef _USB_DISK_DEBUG
299*53ee8cc1Swenshuai.xi         diag_printf("[%s][%d] ==============================\n", __FUNCTION__, __LINE__);
300*53ee8cc1Swenshuai.xi         diag_printf("[%s][%d] %d %d %x %d 0x%08x\n", __FUNCTION__, __LINE__,
301*53ee8cc1Swenshuai.xi             usb_info->uPort, usb_info->uLunNum, block_num, len , (int)buf);
302*53ee8cc1Swenshuai.xi         dump_data(buf, len* 512);
303*53ee8cc1Swenshuai.xi         //dump_data(buf, 8);
304*53ee8cc1Swenshuai.xi         diag_printf("[%s][%d] ==============================\n", __FUNCTION__, __LINE__);
305*53ee8cc1Swenshuai.xi         #endif
306*53ee8cc1Swenshuai.xi 
307*53ee8cc1Swenshuai.xi         return ENOERR;
308*53ee8cc1Swenshuai.xi     }
309*53ee8cc1Swenshuai.xi     else
310*53ee8cc1Swenshuai.xi     {
311*53ee8cc1Swenshuai.xi         //diag_printf("[%s][%d] IO error!!!!\n", __FUNCTION__, __LINE__);
312*53ee8cc1Swenshuai.xi         return -EIO;
313*53ee8cc1Swenshuai.xi     }
314*53ee8cc1Swenshuai.xi }
315*53ee8cc1Swenshuai.xi 
316*53ee8cc1Swenshuai.xi static Cyg_ErrNo
usb_disk_write(disk_channel * chan,const void * buf,cyg_uint32 len,cyg_uint32 block_num)317*53ee8cc1Swenshuai.xi usb_disk_write(disk_channel *chan,
318*53ee8cc1Swenshuai.xi                  const void   *buf,
319*53ee8cc1Swenshuai.xi                  cyg_uint32    len,
320*53ee8cc1Swenshuai.xi                  cyg_uint32    block_num)
321*53ee8cc1Swenshuai.xi {
322*53ee8cc1Swenshuai.xi     usb_disk_info_t *usb_info = (usb_disk_info_t *)chan->dev_priv;
323*53ee8cc1Swenshuai.xi 
324*53ee8cc1Swenshuai.xi     if ((usb_info->uPort == -1) ||
325*53ee8cc1Swenshuai.xi         (usb_info->uLunNum == -1) ||
326*53ee8cc1Swenshuai.xi         (usb_info->DevId == -1) )
327*53ee8cc1Swenshuai.xi     {
328*53ee8cc1Swenshuai.xi         diag_printf("Err: usb_disk_write: device not exist\n");
329*53ee8cc1Swenshuai.xi         return ENODEV;
330*53ee8cc1Swenshuai.xi     }
331*53ee8cc1Swenshuai.xi 
332*53ee8cc1Swenshuai.xi     //kevinhuang, no write temporarily coz current FATFS will contaminate FS on the disk
333*53ee8cc1Swenshuai.xi 	if (ms_bSCSI_Write_10(usb_info->uPort, usb_info->uLunNum, block_num,
334*53ee8cc1Swenshuai.xi 					len, (cyg_uint8*) buf) )
335*53ee8cc1Swenshuai.xi         return ENOERR;
336*53ee8cc1Swenshuai.xi     else
337*53ee8cc1Swenshuai.xi     {
338*53ee8cc1Swenshuai.xi         //diag_printf("[%s][%d] IO error!!!!\n", __FUNCTION__, __LINE__);
339*53ee8cc1Swenshuai.xi         return -EIO;
340*53ee8cc1Swenshuai.xi     }
341*53ee8cc1Swenshuai.xi }
342*53ee8cc1Swenshuai.xi 
343*53ee8cc1Swenshuai.xi static Cyg_ErrNo
usb_disk_get_config(disk_channel * chan,cyg_uint32 key,const void * xbuf,cyg_uint32 * len)344*53ee8cc1Swenshuai.xi usb_disk_get_config(disk_channel *chan,
345*53ee8cc1Swenshuai.xi                       cyg_uint32    key,
346*53ee8cc1Swenshuai.xi                       const void   *xbuf,
347*53ee8cc1Swenshuai.xi                       cyg_uint32   *len)
348*53ee8cc1Swenshuai.xi {
349*53ee8cc1Swenshuai.xi     usb_disk_info_t *usb_info = (usb_disk_info_t *)chan->dev_priv;
350*53ee8cc1Swenshuai.xi     struct LUN_Device   *LunDevice;
351*53ee8cc1Swenshuai.xi 
352*53ee8cc1Swenshuai.xi     if ((usb_info->uPort == -1) ||
353*53ee8cc1Swenshuai.xi         (usb_info->uLunNum == -1) ||
354*53ee8cc1Swenshuai.xi         (usb_info->DevId == -1) )
355*53ee8cc1Swenshuai.xi     {
356*53ee8cc1Swenshuai.xi         diag_printf("Err: usb_disk_get_config: device not exist\n");
357*53ee8cc1Swenshuai.xi         return ENODEV;
358*53ee8cc1Swenshuai.xi     }
359*53ee8cc1Swenshuai.xi 
360*53ee8cc1Swenshuai.xi     switch(key)
361*53ee8cc1Swenshuai.xi     {
362*53ee8cc1Swenshuai.xi         case CYG_IO_GET_CONFIG_WRITE_BLOCKING:
363*53ee8cc1Swenshuai.xi             LunDevice = Mass_stor_us[usb_info->uPort]->msc_device;
364*53ee8cc1Swenshuai.xi             xbuf = &LunDevice[usb_info->uLunNum].bWriteProtect;
365*53ee8cc1Swenshuai.xi             *len = 1;
366*53ee8cc1Swenshuai.xi             return ENOERR;
367*53ee8cc1Swenshuai.xi 
368*53ee8cc1Swenshuai.xi         default:
369*53ee8cc1Swenshuai.xi             return -EINVAL;
370*53ee8cc1Swenshuai.xi     }
371*53ee8cc1Swenshuai.xi     //return -EINVAL;
372*53ee8cc1Swenshuai.xi }
373*53ee8cc1Swenshuai.xi 
374*53ee8cc1Swenshuai.xi static Cyg_ErrNo
usb_disk_set_config(disk_channel * chan,cyg_uint32 key,const void * xbuf,cyg_uint32 * len)375*53ee8cc1Swenshuai.xi usb_disk_set_config(disk_channel *chan,
376*53ee8cc1Swenshuai.xi                       cyg_uint32    key,
377*53ee8cc1Swenshuai.xi                       const void   *xbuf,
378*53ee8cc1Swenshuai.xi                       cyg_uint32   *len)
379*53ee8cc1Swenshuai.xi {
380*53ee8cc1Swenshuai.xi     Cyg_ErrNo                   result  = ENOERR;
381*53ee8cc1Swenshuai.xi     // cyg_mmc_bus_device*    disk    = (cyg_mmc_bus_device*) chan->dev_priv;
382*53ee8cc1Swenshuai.xi     //    cyg_disk_info_t *info = chan->info;
383*53ee8cc1Swenshuai.xi 
384*53ee8cc1Swenshuai.xi     switch(key)
385*53ee8cc1Swenshuai.xi     {
386*53ee8cc1Swenshuai.xi         case CYG_IO_SET_CONFIG_DISK_MOUNT:
387*53ee8cc1Swenshuai.xi             // There will have been a successful lookup(), so there's
388*53ee8cc1Swenshuai.xi             // little point in checking the disk again.
389*53ee8cc1Swenshuai.xi             // if ((sd_chk_ready()!=_DEVICE_READY)&&
390*53ee8cc1Swenshuai.xi             //     result=-EINVAL;
391*53ee8cc1Swenshuai.xi             //else device is OK
392*53ee8cc1Swenshuai.xi 
393*53ee8cc1Swenshuai.xi             break;
394*53ee8cc1Swenshuai.xi 
395*53ee8cc1Swenshuai.xi         case CYG_IO_SET_CONFIG_DISK_UMOUNT:
396*53ee8cc1Swenshuai.xi             if (0 == chan->info->mounts)
397*53ee8cc1Swenshuai.xi             {
398*53ee8cc1Swenshuai.xi                 //cyg_mmc_bus* bus = disk->mmc_bus_dev;
399*53ee8cc1Swenshuai.xi 
400*53ee8cc1Swenshuai.xi                 // If this is the last unmount of the card, mark it as
401*53ee8cc1Swenshuai.xi                 // disconnected. If the user then removes the card and
402*53ee8cc1Swenshuai.xi                 // plugs in a new one everything works cleanly.
403*53ee8cc1Swenshuai.xi                 // disk->mmc_connected = false;
404*53ee8cc1Swenshuai.xi                 // info->connected = false;
405*53ee8cc1Swenshuai.xi                 //result = (chan->callbacks->disk_disconnected)(chan);
406*53ee8cc1Swenshuai.xi 
407*53ee8cc1Swenshuai.xi                 // * deselect it too if it had been selected * //
408*53ee8cc1Swenshuai.xi                 // * We don't care about any error really. This device is going away. * //
409*53ee8cc1Swenshuai.xi                 //mmc_bus_select_card( bus, NULL );
410*53ee8cc1Swenshuai.xi             }
411*53ee8cc1Swenshuai.xi             break;
412*53ee8cc1Swenshuai.xi     }
413*53ee8cc1Swenshuai.xi 
414*53ee8cc1Swenshuai.xi     return result;
415*53ee8cc1Swenshuai.xi     // return -EINVAL;
416*53ee8cc1Swenshuai.xi 
417*53ee8cc1Swenshuai.xi }
418*53ee8cc1Swenshuai.xi #endif
419*53ee8cc1Swenshuai.xi 
420*53ee8cc1Swenshuai.xi extern struct ms_usdata *Mass_stor_us[];
MDrv_USB_MscLookupHostID(char * str)421*53ee8cc1Swenshuai.xi U8 MDrv_USB_MscLookupHostID(char *str)
422*53ee8cc1Swenshuai.xi {
423*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
424*53ee8cc1Swenshuai.xi     disk_channel        *chan;
425*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
426*53ee8cc1Swenshuai.xi     U8 host_id = 0xff;
427*53ee8cc1Swenshuai.xi 
428*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
429*53ee8cc1Swenshuai.xi     {
430*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
431*53ee8cc1Swenshuai.xi             continue;
432*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
433*53ee8cc1Swenshuai.xi         if (chan == NULL)
434*53ee8cc1Swenshuai.xi             continue;
435*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
436*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
437*53ee8cc1Swenshuai.xi             continue;
438*53ee8cc1Swenshuai.xi 
439*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(str, t->name) == 0)) // find the table entry
440*53ee8cc1Swenshuai.xi         {
441*53ee8cc1Swenshuai.xi             host_id = Mass_stor_us[p_usb_info->uPort]->host_id;
442*53ee8cc1Swenshuai.xi             break;
443*53ee8cc1Swenshuai.xi         }
444*53ee8cc1Swenshuai.xi     }
445*53ee8cc1Swenshuai.xi     if (host_id == 0xff)
446*53ee8cc1Swenshuai.xi         diag_printf("Not found %s on any USB host port\n", str);
447*53ee8cc1Swenshuai.xi     return (host_id);
448*53ee8cc1Swenshuai.xi }
449*53ee8cc1Swenshuai.xi 
MDrv_USB_MscLookupManufacturerString(char * str)450*53ee8cc1Swenshuai.xi char *MDrv_USB_MscLookupManufacturerString(char *str)
451*53ee8cc1Swenshuai.xi {
452*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
453*53ee8cc1Swenshuai.xi     disk_channel        *chan;
454*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
455*53ee8cc1Swenshuai.xi     char *pstr;
456*53ee8cc1Swenshuai.xi 
457*53ee8cc1Swenshuai.xi     pstr = NULL;
458*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
459*53ee8cc1Swenshuai.xi     {
460*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
461*53ee8cc1Swenshuai.xi             continue;
462*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
463*53ee8cc1Swenshuai.xi         if (chan == NULL)
464*53ee8cc1Swenshuai.xi             continue;
465*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
466*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
467*53ee8cc1Swenshuai.xi             continue;
468*53ee8cc1Swenshuai.xi 
469*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(str, t->name) == 0)) // find the table entry
470*53ee8cc1Swenshuai.xi         {
471*53ee8cc1Swenshuai.xi             pstr = Mass_stor_us[p_usb_info->uPort]->pusb_dev->pManufacturerString;
472*53ee8cc1Swenshuai.xi             break;
473*53ee8cc1Swenshuai.xi         }
474*53ee8cc1Swenshuai.xi     }
475*53ee8cc1Swenshuai.xi     if (pstr == NULL)
476*53ee8cc1Swenshuai.xi         diag_printf("Manufacturer string not found\n");
477*53ee8cc1Swenshuai.xi     return (pstr);
478*53ee8cc1Swenshuai.xi }
479*53ee8cc1Swenshuai.xi 
MDrv_USB_MscLookupProductString(char * str)480*53ee8cc1Swenshuai.xi char *MDrv_USB_MscLookupProductString(char *str)
481*53ee8cc1Swenshuai.xi {
482*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
483*53ee8cc1Swenshuai.xi     disk_channel        *chan;
484*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
485*53ee8cc1Swenshuai.xi     char *pstr;
486*53ee8cc1Swenshuai.xi 
487*53ee8cc1Swenshuai.xi     pstr = NULL;
488*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
489*53ee8cc1Swenshuai.xi     {
490*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
491*53ee8cc1Swenshuai.xi             continue;
492*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
493*53ee8cc1Swenshuai.xi         if (chan == NULL)
494*53ee8cc1Swenshuai.xi             continue;
495*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
496*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
497*53ee8cc1Swenshuai.xi             continue;
498*53ee8cc1Swenshuai.xi 
499*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(str, t->name) == 0)) // find the table entry
500*53ee8cc1Swenshuai.xi         {
501*53ee8cc1Swenshuai.xi             pstr = Mass_stor_us[p_usb_info->uPort]->pusb_dev->pProductString;
502*53ee8cc1Swenshuai.xi             break;
503*53ee8cc1Swenshuai.xi         }
504*53ee8cc1Swenshuai.xi     }
505*53ee8cc1Swenshuai.xi     if (pstr == NULL)
506*53ee8cc1Swenshuai.xi         diag_printf("Product string not found\n");
507*53ee8cc1Swenshuai.xi     return (pstr);
508*53ee8cc1Swenshuai.xi }
509*53ee8cc1Swenshuai.xi 
MDrv_USB_MscLookupSerialNumberString(char * str)510*53ee8cc1Swenshuai.xi char *MDrv_USB_MscLookupSerialNumberString(char *str)
511*53ee8cc1Swenshuai.xi {
512*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
513*53ee8cc1Swenshuai.xi     disk_channel        *chan;
514*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
515*53ee8cc1Swenshuai.xi     char *pstr;
516*53ee8cc1Swenshuai.xi 
517*53ee8cc1Swenshuai.xi     pstr = NULL;
518*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
519*53ee8cc1Swenshuai.xi     {
520*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
521*53ee8cc1Swenshuai.xi             continue;
522*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
523*53ee8cc1Swenshuai.xi         if (chan == NULL)
524*53ee8cc1Swenshuai.xi             continue;
525*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
526*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
527*53ee8cc1Swenshuai.xi             continue;
528*53ee8cc1Swenshuai.xi 
529*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(str, t->name) == 0)) // find the table entry
530*53ee8cc1Swenshuai.xi         {
531*53ee8cc1Swenshuai.xi             pstr = Mass_stor_us[p_usb_info->uPort]->pusb_dev->pSerialNumberString;
532*53ee8cc1Swenshuai.xi             break;
533*53ee8cc1Swenshuai.xi         }
534*53ee8cc1Swenshuai.xi     }
535*53ee8cc1Swenshuai.xi     if (pstr == NULL)
536*53ee8cc1Swenshuai.xi         diag_printf("Serial Number string not found\n");
537*53ee8cc1Swenshuai.xi     return (pstr);
538*53ee8cc1Swenshuai.xi }
539*53ee8cc1Swenshuai.xi 
MDrv_USB_MscLookupVidPid(char * str)540*53ee8cc1Swenshuai.xi MS_U32 MDrv_USB_MscLookupVidPid(char *str)
541*53ee8cc1Swenshuai.xi {
542*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
543*53ee8cc1Swenshuai.xi     disk_channel        *chan;
544*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
545*53ee8cc1Swenshuai.xi     MS_U32 vid_pid = 0;
546*53ee8cc1Swenshuai.xi 
547*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
548*53ee8cc1Swenshuai.xi     {
549*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
550*53ee8cc1Swenshuai.xi             continue;
551*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
552*53ee8cc1Swenshuai.xi         if (chan == NULL)
553*53ee8cc1Swenshuai.xi             continue;
554*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
555*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
556*53ee8cc1Swenshuai.xi             continue;
557*53ee8cc1Swenshuai.xi 
558*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(str, t->name) == 0)) // find the table entry
559*53ee8cc1Swenshuai.xi         {
560*53ee8cc1Swenshuai.xi             vid_pid = Mass_stor_us[p_usb_info->uPort]->pusb_dev->descriptor.idVendor << 16;
561*53ee8cc1Swenshuai.xi             vid_pid |= Mass_stor_us[p_usb_info->uPort]->pusb_dev->descriptor.idProduct;
562*53ee8cc1Swenshuai.xi             break;
563*53ee8cc1Swenshuai.xi         }
564*53ee8cc1Swenshuai.xi     }
565*53ee8cc1Swenshuai.xi     if (vid_pid == 0)
566*53ee8cc1Swenshuai.xi         diag_printf("Not found %s on any USB host port\n", str);
567*53ee8cc1Swenshuai.xi     return (vid_pid);
568*53ee8cc1Swenshuai.xi }
569*53ee8cc1Swenshuai.xi 
MDrv_USB_Quirk_Add_3G(U32 vid_pid)570*53ee8cc1Swenshuai.xi int MDrv_USB_Quirk_Add_3G(U32 vid_pid)
571*53ee8cc1Swenshuai.xi {
572*53ee8cc1Swenshuai.xi     return quirk_list_add_3g(vid_pid);
573*53ee8cc1Swenshuai.xi }
574*53ee8cc1Swenshuai.xi 
MDrv_USB_IOCTL_Cmd(char * strDevPath,enum usb_ioctl_cmd cmd_type,void * pData)575*53ee8cc1Swenshuai.xi int MDrv_USB_IOCTL_Cmd(char *strDevPath, enum usb_ioctl_cmd cmd_type, void *pData)
576*53ee8cc1Swenshuai.xi {
577*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
578*53ee8cc1Swenshuai.xi     disk_channel        *chan;
579*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info, *pUsbInfo = NULL;
580*53ee8cc1Swenshuai.xi     struct ms_usdata *ms_us;
581*53ee8cc1Swenshuai.xi     int retval = 0;
582*53ee8cc1Swenshuai.xi 
583*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
584*53ee8cc1Swenshuai.xi     {
585*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
586*53ee8cc1Swenshuai.xi             continue;
587*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
588*53ee8cc1Swenshuai.xi         if (chan == NULL)
589*53ee8cc1Swenshuai.xi             continue;
590*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
591*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
592*53ee8cc1Swenshuai.xi             continue;
593*53ee8cc1Swenshuai.xi 
594*53ee8cc1Swenshuai.xi         if ((p_usb_info->DevId != (-1)) && (strcmp(strDevPath, t->name) == 0)) // find the table entry
595*53ee8cc1Swenshuai.xi         {
596*53ee8cc1Swenshuai.xi             pUsbInfo = p_usb_info;
597*53ee8cc1Swenshuai.xi             break;
598*53ee8cc1Swenshuai.xi         }
599*53ee8cc1Swenshuai.xi     }
600*53ee8cc1Swenshuai.xi 
601*53ee8cc1Swenshuai.xi     if (pUsbInfo == NULL)
602*53ee8cc1Swenshuai.xi     {
603*53ee8cc1Swenshuai.xi         diag_printf("[USB] Not found %s on any USB host port\n", strDevPath);
604*53ee8cc1Swenshuai.xi         retval = -ENODEV;
605*53ee8cc1Swenshuai.xi         goto done;
606*53ee8cc1Swenshuai.xi     }
607*53ee8cc1Swenshuai.xi 
608*53ee8cc1Swenshuai.xi     if ((ms_us = Mass_stor_us[pUsbInfo->uPort]) == NULL)
609*53ee8cc1Swenshuai.xi     {
610*53ee8cc1Swenshuai.xi        retval = -ENODEV ;
611*53ee8cc1Swenshuai.xi        goto done;
612*53ee8cc1Swenshuai.xi     }
613*53ee8cc1Swenshuai.xi 
614*53ee8cc1Swenshuai.xi     switch(cmd_type)
615*53ee8cc1Swenshuai.xi     {
616*53ee8cc1Swenshuai.xi         case USB_IOCTL_CTRL:
617*53ee8cc1Swenshuai.xi             retval = ms_ioctl_issue_ctrl(ms_us, pData);
618*53ee8cc1Swenshuai.xi             if(retval < 0)
619*53ee8cc1Swenshuai.xi             {
620*53ee8cc1Swenshuai.xi                 retval = -EIO;
621*53ee8cc1Swenshuai.xi             }
622*53ee8cc1Swenshuai.xi             break;
623*53ee8cc1Swenshuai.xi 
624*53ee8cc1Swenshuai.xi         case USB_IOCTL_BULK:
625*53ee8cc1Swenshuai.xi             retval = ms_ioctl_issue_bulk(ms_us, pData);
626*53ee8cc1Swenshuai.xi             if(retval < 0)
627*53ee8cc1Swenshuai.xi             {
628*53ee8cc1Swenshuai.xi                 retval = -EIO;
629*53ee8cc1Swenshuai.xi             }
630*53ee8cc1Swenshuai.xi             break;
631*53ee8cc1Swenshuai.xi 
632*53ee8cc1Swenshuai.xi         default:
633*53ee8cc1Swenshuai.xi             retval = -EINVAL;
634*53ee8cc1Swenshuai.xi             diag_printf("[USB] unknow USB_IOCTL type!!\n");
635*53ee8cc1Swenshuai.xi             break;
636*53ee8cc1Swenshuai.xi     }
637*53ee8cc1Swenshuai.xi done:
638*53ee8cc1Swenshuai.xi     return retval;
639*53ee8cc1Swenshuai.xi }
640*53ee8cc1Swenshuai.xi 
RemoveUSBDiskPort(U8 uPort,U8 uLunNum)641*53ee8cc1Swenshuai.xi VOID RemoveUSBDiskPort(U8 uPort, U8 uLunNum)
642*53ee8cc1Swenshuai.xi {
643*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *dev_h, *t;
644*53ee8cc1Swenshuai.xi     disk_channel        *chan;
645*53ee8cc1Swenshuai.xi     //cyg_disk_info_t     *info;
646*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
647*53ee8cc1Swenshuai.xi     char                szUSBDevName[12]={0};
648*53ee8cc1Swenshuai.xi 
649*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
650*53ee8cc1Swenshuai.xi     {
651*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
652*53ee8cc1Swenshuai.xi             continue;
653*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
654*53ee8cc1Swenshuai.xi         if (chan == NULL)
655*53ee8cc1Swenshuai.xi             continue;
656*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
657*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
658*53ee8cc1Swenshuai.xi             continue;
659*53ee8cc1Swenshuai.xi 
660*53ee8cc1Swenshuai.xi         if (p_usb_info->DevId == ((uPort+1)*MAX_USB_MSC_LUNS + uLunNum))
661*53ee8cc1Swenshuai.xi         {
662*53ee8cc1Swenshuai.xi             if ((p_usb_info->uPort != uPort) || (p_usb_info->uLunNum != uLunNum))
663*53ee8cc1Swenshuai.xi             {
664*53ee8cc1Swenshuai.xi                 diag_printf("Warning: RemoveUSBDiskPort not match !!\n");
665*53ee8cc1Swenshuai.xi                 diag_printf("[Port lun]: [%d %d]->[%d %d]\n", uPort,uLunNum,p_usb_info->uPort,p_usb_info->uLunNum);
666*53ee8cc1Swenshuai.xi             }
667*53ee8cc1Swenshuai.xi             diag_printf("RemoveUSBDiskPort:%d %d %d\n",p_usb_info->uPort,p_usb_info->uLunNum,p_usb_info->DevId);
668*53ee8cc1Swenshuai.xi             break;
669*53ee8cc1Swenshuai.xi         }
670*53ee8cc1Swenshuai.xi     }
671*53ee8cc1Swenshuai.xi 
672*53ee8cc1Swenshuai.xi     if (t == &__DEVTAB_END__)
673*53ee8cc1Swenshuai.xi     {
674*53ee8cc1Swenshuai.xi         diag_printf("RemoveUSBDiskPort: Can't find match Port:%d Lun:%d\n", uPort, uLunNum);
675*53ee8cc1Swenshuai.xi         return;
676*53ee8cc1Swenshuai.xi     }
677*53ee8cc1Swenshuai.xi 
678*53ee8cc1Swenshuai.xi     dev_h = t;
679*53ee8cc1Swenshuai.xi     chan = (disk_channel *) dev_h->priv;
680*53ee8cc1Swenshuai.xi     //info = chan->info;
681*53ee8cc1Swenshuai.xi     p_usb_info = (usb_disk_info_t *) chan->dev_priv;
682*53ee8cc1Swenshuai.xi     p_usb_info->DevId = -1;
683*53ee8cc1Swenshuai.xi     p_usb_info->uPort = -1;
684*53ee8cc1Swenshuai.xi     p_usb_info->uLunNum = -1;
685*53ee8cc1Swenshuai.xi 
686*53ee8cc1Swenshuai.xi     diag_printf("Remove USB disk %s\n", dev_h->name);
687*53ee8cc1Swenshuai.xi     chan->callbacks->disk_disconnected(chan);
688*53ee8cc1Swenshuai.xi 
689*53ee8cc1Swenshuai.xi     if ( _DrvUSB_CBFun != NULL )
690*53ee8cc1Swenshuai.xi     {
691*53ee8cc1Swenshuai.xi         if (strlen(dev_h->name) < 12)
692*53ee8cc1Swenshuai.xi             strcpy(szUSBDevName, dev_h->name);
693*53ee8cc1Swenshuai.xi         osapi_spin_lock_irq (&hcd_root_hub_lock); // callback function should be locked
694*53ee8cc1Swenshuai.xi         _DrvUSB_CBFun(USB_PLUG_OUT, USB_EVENT_DEV_TYPE_STOR, szUSBDevName);
695*53ee8cc1Swenshuai.xi         osapi_spin_unlock_irq (&hcd_root_hub_lock);
696*53ee8cc1Swenshuai.xi     }
697*53ee8cc1Swenshuai.xi }
698*53ee8cc1Swenshuai.xi 
ConnectUSBDisk(U8 uPort,U8 uLunNum)699*53ee8cc1Swenshuai.xi BOOL ConnectUSBDisk(U8 uPort, U8 uLunNum)
700*53ee8cc1Swenshuai.xi {
701*53ee8cc1Swenshuai.xi     struct LUN_Device   *LunDevice = Mass_stor_us[uPort]->msc_device;
702*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *dev_h;
703*53ee8cc1Swenshuai.xi     disk_channel        *chan;
704*53ee8cc1Swenshuai.xi     usb_disk_info_t     *p_usb_info;
705*53ee8cc1Swenshuai.xi     cyg_disk_identify_t ident;
706*53ee8cc1Swenshuai.xi     cyg_devtab_entry_t  *t;
707*53ee8cc1Swenshuai.xi     char                szUSBDevName[12]={0};
708*53ee8cc1Swenshuai.xi 
709*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
710*53ee8cc1Swenshuai.xi     {
711*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
712*53ee8cc1Swenshuai.xi             continue;
713*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
714*53ee8cc1Swenshuai.xi         if (chan == NULL)
715*53ee8cc1Swenshuai.xi             continue;
716*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
717*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
718*53ee8cc1Swenshuai.xi             continue;
719*53ee8cc1Swenshuai.xi         if (p_usb_info->DevId == ((uPort+1)*MAX_USB_MSC_LUNS + uLunNum) )
720*53ee8cc1Swenshuai.xi         {
721*53ee8cc1Swenshuai.xi             diag_printf("Warning : find one previous device here !!\n");
722*53ee8cc1Swenshuai.xi             RemoveUSBDiskPort(uPort, uLunNum);
723*53ee8cc1Swenshuai.xi             p_usb_info->DevId = -1;
724*53ee8cc1Swenshuai.xi         }
725*53ee8cc1Swenshuai.xi     }
726*53ee8cc1Swenshuai.xi 
727*53ee8cc1Swenshuai.xi     for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
728*53ee8cc1Swenshuai.xi     {
729*53ee8cc1Swenshuai.xi         if(!is_usb_block_dev(t))
730*53ee8cc1Swenshuai.xi             continue;
731*53ee8cc1Swenshuai.xi         chan = (disk_channel *) t->priv;
732*53ee8cc1Swenshuai.xi         if (chan == NULL)
733*53ee8cc1Swenshuai.xi             continue;
734*53ee8cc1Swenshuai.xi         p_usb_info = (usb_disk_info_t *) chan->dev_priv;
735*53ee8cc1Swenshuai.xi         if (p_usb_info == NULL)
736*53ee8cc1Swenshuai.xi             continue;
737*53ee8cc1Swenshuai.xi 
738*53ee8cc1Swenshuai.xi         if (p_usb_info->DevId == (-1))
739*53ee8cc1Swenshuai.xi         {
740*53ee8cc1Swenshuai.xi             p_usb_info->DevId = (uPort+1)*MAX_USB_MSC_LUNS + uLunNum;
741*53ee8cc1Swenshuai.xi             break;
742*53ee8cc1Swenshuai.xi         }
743*53ee8cc1Swenshuai.xi     }
744*53ee8cc1Swenshuai.xi 
745*53ee8cc1Swenshuai.xi     if (t == &__DEVTAB_END__)
746*53ee8cc1Swenshuai.xi     {
747*53ee8cc1Swenshuai.xi         diag_printf("Error! Can't find available disk name. Exceed maximum support number!\n");
748*53ee8cc1Swenshuai.xi         return FALSE;
749*53ee8cc1Swenshuai.xi     }
750*53ee8cc1Swenshuai.xi 
751*53ee8cc1Swenshuai.xi     chan = (disk_channel *) t->priv;
752*53ee8cc1Swenshuai.xi     chan->info->connected = true;
753*53ee8cc1Swenshuai.xi 
754*53ee8cc1Swenshuai.xi     dev_h = t;
755*53ee8cc1Swenshuai.xi 
756*53ee8cc1Swenshuai.xi     chan = (disk_channel*) dev_h->priv;
757*53ee8cc1Swenshuai.xi     p_usb_info = (usb_disk_info_t *) chan->dev_priv;
758*53ee8cc1Swenshuai.xi     p_usb_info->uPort = uPort;
759*53ee8cc1Swenshuai.xi     p_usb_info->uLunNum = uLunNum;
760*53ee8cc1Swenshuai.xi 
761*53ee8cc1Swenshuai.xi     ident.serial[0]       = '\0';
762*53ee8cc1Swenshuai.xi     ident.firmware_rev[0] = '\0';
763*53ee8cc1Swenshuai.xi     ident.model_num[0]    = '\0';
764*53ee8cc1Swenshuai.xi     // ident.lba_sectors_num = usb_info->size / 512;
765*53ee8cc1Swenshuai.xi     ident.lba_sectors_num = LunDevice[uLunNum].u32BlockTotalNum;
766*53ee8cc1Swenshuai.xi     ident.cylinders_num   = 0;
767*53ee8cc1Swenshuai.xi     ident.heads_num       = 0;
768*53ee8cc1Swenshuai.xi     ident.sectors_num     = 0;
769*53ee8cc1Swenshuai.xi     ident.phys_block_size = LunDevice[uLunNum].u32BlockSize;
770*53ee8cc1Swenshuai.xi     ident.max_transfer    = LunDevice[uLunNum].u32BlockSize;//  512;
771*53ee8cc1Swenshuai.xi 
772*53ee8cc1Swenshuai.xi     diag_printf("Connect USB disk %s, path usb:%s\n", dev_h->name, Mass_stor_us[uPort]->pusb_dev->devpath);
773*53ee8cc1Swenshuai.xi     diag_printf("Port device number:%d Lun:%d Id:%d\n", p_usb_info->uPort, p_usb_info->uLunNum, p_usb_info->DevId);
774*53ee8cc1Swenshuai.xi     if (!(chan->callbacks->disk_init)(dev_h))
775*53ee8cc1Swenshuai.xi         return FALSE;
776*53ee8cc1Swenshuai.xi 
777*53ee8cc1Swenshuai.xi     if (ENOERR != (chan->callbacks->disk_connected)(dev_h, &ident))
778*53ee8cc1Swenshuai.xi         return FALSE;
779*53ee8cc1Swenshuai.xi 
780*53ee8cc1Swenshuai.xi     if ( _DrvUSB_CBFun != NULL )
781*53ee8cc1Swenshuai.xi     {
782*53ee8cc1Swenshuai.xi         if (strlen(dev_h->name) < 12)
783*53ee8cc1Swenshuai.xi             strcpy(szUSBDevName, dev_h->name);
784*53ee8cc1Swenshuai.xi         _DrvUSB_CBFun(USB_PLUG_IN, USB_EVENT_DEV_TYPE_STOR, szUSBDevName);
785*53ee8cc1Swenshuai.xi     }
786*53ee8cc1Swenshuai.xi     //Test
787*53ee8cc1Swenshuai.xi     //ret = mount("/dev/sda/1", "/", "fatfs");
788*53ee8cc1Swenshuai.xi     //diag_printf("mount status : %d \n", ret);
789*53ee8cc1Swenshuai.xi     diag_printf("@@ Host ID %x\n", MDrv_USB_MscLookupHostID(szUSBDevName));
790*53ee8cc1Swenshuai.xi     return TRUE;
791*53ee8cc1Swenshuai.xi }
792*53ee8cc1Swenshuai.xi 
793