1 /*
2 ********************************************************************************************************************
3 *                                              usb host driver
4 *
5 *                              (c) Copyright 2007-2010, javen.China
6 *                                       All Rights Reserved
7 *
8 * File Name     : Disk.c
9 *
10 * Author        : javen
11 *
12 * Version       : 2.0
13 *
14 * Date          : 2010.03.02
15 *
16 * Description   :
17 *
18 * History       :
19 *
20 ********************************************************************************************************************
21 */
22 #include  "usb_os_platform.h"
23 #include  "error.h"
24 #include  "usb_msc_i.h"
25 #include  "Scsi2.h"
26 #include  "LunMgr_i.h"
27 #include  "BlkDev.h"
28 
29 /*
30 *******************************************************************************
31 *                     DiskMediaChange
32 *
33 * Description:
34 *
35 *
36 * Parameters:
37 *
38 *
39 * Return value:
40 *    无
41 *
42 * note:
43 *    无
44 *
45 *******************************************************************************
46 */
DiskMediaChange(__mscLun_t * mscLun)47 static void DiskMediaChange(__mscLun_t *mscLun)
48 {
49     __UsbBlkDev_t *BlkDev = NULL;
50     int ret = USB_STATUS_SUCCESS;
51 
52     if (mscLun == NULL)
53     {
54         hal_log_err("ERR: DiskMediaChange: mscLun == NULL");
55         return;
56     }
57 
58     BlkDev = (__UsbBlkDev_t *)mscLun->sdev_data;
59 
60     if (BlkDev == NULL)
61     {
62         hal_log_err("ERR: DiskMediaChange: BlkDev == NULL");
63         return;
64     }
65 
66     hal_sem_wait(mscLun->Lock);
67     ret = ScsiTestUnitReady(mscLun);
68     hal_sem_post(mscLun->Lock);
69 
70     switch (ret)
71     {
72         case USB_STATUS_SUCCESS:
73 
74             /* 没有注册disk设备, 就去注册disk设备 */
75             if (!BlkDev->is_RegDisk)
76             {
77                 /* 获得磁盘信息 */
78                 GetDiskInfo(BlkDev);
79 
80                 /* 注册块设备 */
81                 if (mscLun->MediaPresent)
82                 {
83                     UsbBlkDevUnReg(BlkDev);
84                     UsbBlkDevReg(BlkDev, DEV_CLASS_DISK, 1);
85                 }
86             }
87 
88             break;
89 
90         case USB_STATUS_MEDIA_NOT_PRESENT:
91             if (BlkDev->is_RegDisk)
92             {
93                 hal_log_err("ERR: DiskMediaChange: media is change");
94                 UsbBlkDevUnReg(BlkDev);
95                 UsbBlkDevReg(BlkDev, DEV_CLASS_USERDEF, 0);
96             }
97 
98             break;
99 
100         case USB_STATUS_NOT_READY_TO_READY_TRANSITION:
101             hal_log_info("[USB Disk]: media not ready to ready transition");
102             break;
103 
104         default:
105             BlkDev->ErrCmdNr++;
106 
107             if (BlkDev->ErrCmdNr > 3)
108             {
109                 hal_log_err("ERR: too much error during test unit ready");
110                 BlkDev->ErrCmdNr = 0;
111 
112                 if (BlkDev->is_RegDisk)
113                 {
114                     UsbBlkDevUnReg(BlkDev);
115                     UsbBlkDevReg(BlkDev, DEV_CLASS_USERDEF, 0);
116                 }
117                 else
118                 {
119                     hal_log_err("ERR: device is not regist a disk device");
120                 }
121             }
122     }
123 
124     return;
125 }
126 
127 /*
128 *******************************************************************************
129 *                     UsbBlkDevOpen
130 *
131 * Description:
132 *
133 *
134 * Parameters:
135 *
136 *
137 * Return value:
138 *    0  :成功
139 *   !0  :失败
140 *
141 * note:
142 *    无
143 *
144 *******************************************************************************
145 */
DiskProbe(__mscLun_t * mscLun)146 int DiskProbe(__mscLun_t *mscLun)
147 {
148     __UsbBlkDev_t *BlkDev = NULL;
149     unsigned int  cpu_sr;
150     int ret = 0;
151 
152     if (mscLun == NULL)
153     {
154         hal_log_err("ERR: DiskProbe: input error");
155         return -1;
156     }
157 
158     /* 初始化一个块设备 */
159     BlkDev = UsbBlkDevAllocInit(mscLun);
160 
161     if (BlkDev == NULL)
162     {
163         hal_log_err("ERR: DiskProbe: alloc blkdev failed");
164         return -1;
165     }
166 
167     mscLun->sdev_data = (void *)BlkDev;
168 
169     if (mscLun->LunNo >= mscLun->mscDev->MaxLun - 1)
170     {
171         BlkDev->last_lun = 1;
172         __wrn("disk, send last lun msg.........");
173     }
174     else
175     {
176         BlkDev->last_lun = 0;
177     }
178 
179     printf("mscLun->LunNo=%d\n", mscLun->LunNo);
180     printf("mscLun->mscDev->MaxLun=%d\n", mscLun->mscDev->MaxLun);
181     printf("BlkDev->last_lun=%d\n", BlkDev->last_lun);
182     /* 获得磁盘信息 */
183     GetDiskInfo(BlkDev);
184 
185     /* 注册块设备 */
186     if (!mscLun->MediaPresent)
187     {
188         ret = UsbBlkDevReg(BlkDev, DEV_CLASS_USERDEF, 0);
189     }
190     else
191     {
192         ret = UsbBlkDevReg(BlkDev, DEV_CLASS_DISK, 1);
193     }
194 
195     if (ret != USB_ERR_SUCCESS)
196     {
197         //DMSG_PANIC("ERR: DiskProbe: UsbBlkDevReg failed");
198         return USB_ERR_REG_BLK_DEV_FAILED;
199     }
200 
201     /* 告诉usb_monitor, scsi disk识别设备成功 */
202     {
203         u32 is_reg = 1;
204         //usbm_sendcmd(DEV_IOC_USR_HWSC_USBH_MSC_DEV_REG_SET, &is_reg);
205     }
206     /*
207          只有可移动设备才需要检查MediaChange,但是在Sata转USB接口的设备里,
208      设备标称自己是不可移动设备,在host没有访问它的时候,设备会进入低功耗模式,
209      设备的电机不转了。当host读设备时,设备的电机开始工作,在传输数据时,产生epstall,
210      对设备进行复位后,设备突然断开。因此只能一直给它发test_unit_ready命令,不让其
211      进入低功耗模式。
212      */
213     ENTER_CRITICAL(cpu_sr);
214     mscLun->MediaChange = DiskMediaChange;
215     EXIT_CRITICAL(cpu_sr);
216     return USB_ERR_SUCCESS;
217 }
218 
219 /*
220 *******************************************************************************
221 *                     UsbBlkDevOpen
222 *
223 * Description:
224 *
225 *
226 * Parameters:
227 *
228 *
229 * Return value:
230 *    0  :成功
231 *   !0  :失败
232 *
233 * note:
234 *    无
235 *
236 *******************************************************************************
237 */
DiskRemove(__mscLun_t * mscLun)238 int DiskRemove(__mscLun_t *mscLun)
239 {
240     __UsbBlkDev_t *BlkDev = NULL;
241     unsigned int  cpu_sr;
242 
243     if (mscLun == NULL)
244     {
245         hal_log_err("ERR: DiskRemove: input error");
246         return -1;
247     }
248 
249     BlkDev = (__UsbBlkDev_t *)mscLun->sdev_data;
250 
251     if (BlkDev == NULL)
252     {
253         hal_log_err("ERR: BlkDev == NULL");
254         return -1;
255     }
256 
257     /* 注销块设备 */
258     UsbBlkDevUnReg(BlkDev);
259     /* 告诉usb_monitor scsi disk设备已经注销 */
260     {
261         u32 is_reg = 0;
262         //usbm_sendcmd(DEV_IOC_USR_HWSC_USBH_MSC_DEV_REG_SET, &is_reg);
263     }
264     ShutDown(BlkDev);
265     /* media change线程已经停止了, 所以现在可以直接删除MediaChange */
266     ENTER_CRITICAL(cpu_sr);
267     mscLun->MediaChange = NULL;
268     EXIT_CRITICAL(cpu_sr);
269     UsbBlkDevFree(BlkDev);
270     mscLun->sdev_data = NULL;
271     return USB_ERR_SUCCESS;
272 }
273 
274 
275