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