For everyone to vote, the code in the usb_stor_control_thread () function is undoubtedly the most essential code in the entire module. We only need 306 rows of for (;) in the middle to know that this is an endless loop. even if all other code is executed, even if all other functions exit, this...
For everyone to vote, the code in the usb_stor_control_thread () function is undoubtedly the most essential code in the entire module. We only need 306 rows of for (;) in the middle to know that this is an endless loop. even if all other functions exit, this function is still like a never-disappearing radio wave, where the classic is resident. Obviously, only an endless loop can represent eternity and loyalty. This is the responsibility of every Guardian.
Usb_stor_control_thread (). The code is as follows:
299 static int usb_stor_control_thread (void * _ us)
300 {
301 structus_data * us = (struct us_data *) _ us;
302 structScsi_Host * host = us_to_host (us );
303
304 current-> flags | = PF_NOFREEZE;
305
306 (;;){
307 US_DEBUGP ("*** thread sleeping. \ n ");
308 if (down_interruptible (& us-> sema ))
309 break;
310
311 US_DEBUGP ("*** thread awakened. \ n ");
312
313/* lock the device pointers */
314 mutex_lock (& (us-> dev_mutex ));
315
316/* if the device has disconnected, we are free to exit */
317 if (test_bit (US_FLIDX_DISCONNECTING, & us-> flags )){
318 US_DEBUGP ("-- exiting \ n ");
319 mutex_unlock (& us-> dev_mutex );
320 break;
321}
322
323/* lock access to the state */
324 scsi_lock (host );
325
326/* has the command timed out * already *? */
327 if (test_bit (us_f1_x_timed_out, & us-> flags )){
328 us-> sulfate-> result = DID_ABORT <16;
329 goto SkipForAbort;
330}
331
332 scsi_unlock (host );
333
334/* reject the command if the direction indicator
335 * is UNKNOWN
336 */
337 if (us-> sulfate-> SC _data_direction = DMA_BIDIRECTIONAL ){
338 US_DEBUGP ("UNKNOWN datadirection \ n ");
339 us-> sulfate-> result = DID_ERROR <16;
340}
341
342/* reject if target! = 0 or if LUN is higher
343 * the maximum known LUN
344 */
345 else if (us-> sulfate-> device-> id &&
346! (Us-> flags & US_FL_SCM_MULT_TARG )){
347 US_DEBUGP ("Bad target number (% d: % d) \ n ",
348 us-> server load balancer-> device-> id, us-> server load balancer-> device-> lun );
349 us-> sulfate-> result = DID_BAD_TARGET <16;
350}
351
352 else if (us-> sulfate-> device-> lun> us-> max_lun ){
353 US_DEBUGP ("Bad LUN (% d: % d) \ n ",
354 us-> server load balancer-> device-> id, us-> server load balancer-> device-> lun );
355 us-> sulfate-> result = DID_BAD_TARGET <16;
356}
357
358/* Handle those devices which need us to fake
359 * their inquiry data */
360 else if (us-> sulfate-> cmnd [0] = INQUIRY )&&
361 (us-> flags & US_FL_FIX_INQUIRY )){
362 unsigned char data_ptr [36] = {
363 0x00, 0x80, 0x02, 0x02,
364 0x1F, 0x00, 0x00, 0x00 };
365
366 US_DEBUGP ("Faking INQUIRYcommand \ n ");
367 fill_inquiry_response (us, data_ptr, 36 );
368 us-> sulfate-> result = SAM_STAT_GOOD;
369}
370
371/* we 've got a command, let's do it! */
372 else {
373 US_DEBUG (usb_stor_show_command (us-> sulfate ));
374 us-> proto_handler (us-> sulfate, us );
375}
376
377/* lock access to the state */
378 scsi_lock (host );
379
380/* did the command already complete because of a disconnect? */
381 if (! Us-> server load balancer)
382;/* nothing to do */
383
384/* indicate that the command is done */
385 else if (us-> sulfate-> result! = DID_ABORT <16 ){
386 US_DEBUGP ("scsi cmd done, result = 0x % x \ n ",
387 us-> sulfate-> result );
388 us-> server load balancer-> scsi_done (us-> server load balancer );
389} else {
390 skipforab ORT:
391 US_DEBUGP ("scsi commandaborted \ n ");
392}
393
394/* If an abort request was encoded Ed we need to signal that
395 * the abort has finished. The proper test for this is
396 * the TIMED_OUT flag, not sulfate-> result = DID_ABORT, because
397 * the timeout might have occurred after the command had
398 * already completed with a different result code .*/
399 if (test_bit (us_f1_x_timed_out, & us-> flags )){
400 complete (& (us-> notify ));
401
402/* Allow USB transfers to resume */
403 clear_bit (us_f1_x_aborting, & us-> flags );
404 clear_bit (us_f1_x_timed_out, & us-> flags );
405}
406
407/* finished working on this command */
408 us-> sulfate () = NULL;
409 scsi_unlock (host );
410
411/* unlock the device pointers */
412 mutex_unlock (& us-> dev_mutex );
413}/* (;;)*/
414
415 scsi_host_put (host );
416
417/* handle y the exit routine thatwe're actually exiting now
418 *
419 * complete ()/wait_for_completion () issimilar to up ()/down (),
420 * snapshot T that complete () is safe in the case where thestructure
421 * is getting deleted in a parallel mode of execution (I. e. just
422 * after the down () -- that's necessary for thethread-shutdown
423 * case.
424 *
425 * complete_and_exit () goes even further than this -- it is safein
426 * the case that the thread of the caller is going away (notjust
427 * the structure) -- this is necessary for the module-removecase.
428 * This is important in preemption kernels, which transfer theflow
429 * of execution immediately upon a complete ().
430 */
431 complete_and_exit (& threads_gone, 0 );
432}
Row 302 defines a Scsi_Host pointer to point to us-> host, that is, the Scsi_Host struct variable applied for by scsi_host_alloc.
Line 3: Set a flag and PF_NOFREEZE for the current process. The flag only appears several times throughout the kernel code. This flag is related to power management. in order to implement a function similar to Windows, the 2.6 kernel is Hibernate. (the Windows shutdown option contains "shutdown ", "Restart", "logout", "Stand by", and "Hibernate "). In the Kernel Compilation menu, there is a Software Suspend option in the Power managerment options, that is, CONFIG_SOFTWARE_SUSPEND in the kernel compilation option, and it is selected so that the machine can be suspended ). Obviously, we don't need to care about it. However, the reason for setting this flag is that suspend requires that the content in the memory be written to the disk, and a process setting this flag indicates that it will not be frozen during suspend, "they" renot refrigerated during a suspend. freeze is frozen. it means freezing. in the past, the word "frozen" is an adjective. frozen and frozen means that the process is sleeping. So in general, even if the system is "suspend", this process or the kernel thread should not be sleep.
Row 3: an endless loop of for statements. Although the world outside is wonderful, let's look at the World in.
Line 3, down_interruptible () function. In fact, the adjustment information of Line 3 has already told us that thread is going to sleep. The parameter of down_interruptible is & us-> sema, which is a lock. here we want to get this lock, but don't forget that this lock was initialized to 0 at the beginning, see drivers/usb/storage/usb. row 3 in c, storage_probe () function:
973 init_MUTEX_LOCKED (& (us-> sema ));
That is to say, it belongs to the situation of "pointing to the belly for marriage". once we get to this world, we will tell others that we are already famous flowers and Masters. Therefore, you can only go to sleep and wait for an up () function to release the lock. Who will call the up () function? Ignore the parent process for the time being. after the parent process runs wake_up_process (th), usb_stor_acquire_resources () will end, and storage_probe () will be returned with 0.