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