Driver/usb/skel_write()

Last-modified: 2007-08-06 (月) 19:02:34

153 :static ssize_t skel_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos)
154 :{
155 : struct usb_skel *dev;
156 : int retval = 0;
157 : struct urb *urb = NULL;
158 : char *buf = NULL;
159 :
160 : dev = (struct usb_skel *)file->private_data;

file->private_dataからdeviceを取得する

161 :
162 : /* verify that we actually have some data to write */
163 : if (count == 0)

count==0(書き込みデータが0)ならば

164 : goto exit;

関数を抜ける

165 :
166 : /* create a urb, and a buffer for it, and copy the data to the urb */
167 : urb = usb_alloc_urb(0, GFP_KERNEL);

USBデバイスと通信するためにはURBブロックが何はともあれ必要。
まずはURBブロックを確保する。

168 : if (!urb) {
169 : retval = -ENOMEM;
170 : goto error;
171 : }
172 :
173 : buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);

バッファを割り当てるけど何で、usb用に特別にあるのかが分からない。

man page of usb_buffer_alloc
174 : if (!buf) {

バッファが取得できないならば

175 : retval = -ENOMEM;
176 : goto error;
177 : }
178 : if (copy_from_user(buf, user_buffer, count)) {

ユーザデータをバッファにコピーする。

179 : retval = -EFAULT;
180 : goto error;
181 : }
182 :
183 : /* initialize the urb properly */
184 : usb_fill_bulk_urb(urb, dev->udev,
185 : usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),

発信ポイントとしてurbブロックを生成する。

186 : buf, count, skel_write_bulk_callback, dev);
187 : urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

転送フラグの設定

188 :
189 : /* send the data out the bulk port */
190 : retval = usb_submit_urb(urb, GFP_KERNEL);

リクエストの送信

191 : if (retval) {
192 : err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
193 : goto error;
194 : }
195 :
196 : /* release our reference to this urb, the USB core will eventually free it entirely */
197 : usb_free_urb(urb);

バッファの解放

198 :
199 :exit:
200 : return count;
201 :
202 :error:
203 : usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
204 : usb_free_urb(urb);
205 : kfree(buf);
206 : return retval;
207 :}