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