func: static sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) int mxsize , cmd_size , k ; int input_size , blocking ; unsigned char opcode ; Sg_device * sdp ; Sg_fd * sfp ; Sg_request * srp ; struct sg_header old_hdr ; unsigned char cmnd [ SG_MAX_CDB_SIZE ] ; if ( ( ! ( sfp = ( Sg_fd * ) filp -> private_data ) ) || ( ! ( sdp = sfp -> parentdp ) ) )  if ( atomic_read ( & sdp -> detaching ) )  if ( ! ( ( filp -> f_flags & O_NONBLOCK ) || scsi_block_when_processing_errors ( sdp -> device ) ) )  if ( ! access_ok ( VERIFY_READ , buf , count ) )  if ( count < SZ_SG_HEADER )  if ( __copy_from_user ( & old_hdr , buf , SZ_SG_HEADER ) )  blocking = ! ( filp -> f_flags & O_NONBLOCK ); if ( old_hdr . reply_len < 0 )  if ( count < ( SZ_SG_HEADER + 6 ) )  if ( ! ( srp = sg_add_request ( sfp ) ) )  static Sg_request sg_add_request(Sg_fd * sfp) int k ; Sg_request * resp ; Sg_request * rp = sfp -> req_arr ; resp = sfp -> headrp; if ( ! resp )  memset ( rp , 0 , sizeof ( Sg_request ) ); rp -> parentfp = sfp; resp = rp; if ( 0 == sfp -> cmd_q )  resp = NULL; if ( k < SG_MAX_QUEUE )  memset ( rp , 0 , sizeof ( Sg_request ) ); rp -> parentfp = sfp; while ( resp -> nextrp )  resp = resp -> nextrp; resp -> nextrp = rp; resp = rp; resp = NULL; if ( resp )  resp -> nextrp = NULL; resp -> header . duration = jiffies_to_msecs ( jiffies ); return resp ; buf += SZ_SG_HEADER; if ( sfp -> next_cmd_len > 0 )  cmd_size = sfp -> next_cmd_len; sfp -> next_cmd_len = 0; cmd_size = COMMAND_SIZE ( opcode ); if ( ( opcode >= 0xc0 ) && old_hdr . twelve_byte )  cmd_size = 12; input_size = count - cmd_size; input_size -= SZ_SG_HEADER; if ( input_size < 0 )  if ( __copy_from_user ( cmnd , buf , cmd_size ) )  k = sg_common_write ( sfp , srp , cmnd , sfp -> timeout , blocking ); static sg_common_write(Sg_fd * sfp, Sg_request * unsigned char *cmnd, int timeout, int blocking) int k , at_head ; srp -> data . cmd_opcode = cmnd [ 0 ]; k = sg_start_req ( srp , cmnd ); static sg_start_req(Sg_request *srp, unsigned char *cmd) struct request * rq ; Sg_fd * sfp = srp -> parentfp ; sg_io_hdr_t * hp = & srp -> header ; struct request_queue * q = sfp -> parentdp -> device -> request_queue ; int rw = hp -> dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ ; unsigned char * long_cmdp = NULL ; if ( hp -> cmd_len > BLK_MAX_CDB )  long_cmdp = kzalloc ( hp -> cmd_len , GFP_KERNEL ); if ( ! long_cmdp )  rq = blk_get_request ( q , rw , GFP_KERNEL ); if ( IS_ERR ( rq ) )  if ( hp -> cmd_len > BLK_MAX_CDB )  rq -> cmd = long_cmdp; memcpy ( rq -> cmd , cmd , hp -> cmd_len ); rq -> cmd_len = hp -> cmd_len; srp -> rq = rq; rq -> end_io_data = srp; rq -> sense = srp -> sense_b; rq -> retries = SG_DEFAULT_RETRIES; sg_link_reserve ( sfp , srp , dxfer_len ); static sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) Sg_scatter_hold * req_schp = & srp -> data ; Sg_scatter_hold * rsv_schp = & sfp -> reserve ; srp -> res_used = 1; SCSI_LOG_TIMEOUT ( 4 , sg_printk ( KERN_INFO , sfp -> parentdp , "sg_link_reserve: size=%d\n" , size ) ); rem = size; num = 1 << ( PAGE_SHIFT + rsv_schp -> page_order ); for (k = 0; k < rsv_schp->k_use_sg; k++) if ( rem <= num )  req_schp -> k_use_sg = k + 1; req_schp -> sglist_len = rsv_schp -> sglist_len; req_schp -> pages = rsv_schp -> pages; req_schp -> bufflen = size; req_schp -> page_order = rsv_schp -> page_order; rem -= num; if ( k >= rsv_schp -> k_use_sg )  SCSI_LOG_TIMEOUT ( 1 , sg_printk ( KERN_INFO , sfp -> parentdp , "sg_link_reserve: BAD size\n" ) ); res = blk_rq_map_user_iov ( q , rq , md , & i , GFP_ATOMIC ); res = blk_rq_map_user ( q , rq , md , hp -> dxferp , hp -> dxfer_len , GFP_ATOMIC ); if ( ! res )  srp -> bio = rq -> bio; return res ; 