func: static int arcmsr_queue_command_lck(struct scsi_cmnd void (* done)(struct scsi_cmnd *)) struct Scsi_Host * host = cmd -> device -> host ; struct AdapterControlBlock * acb = ( struct AdapterControlBlock * ) host -> hostdata ; int target = cmd -> device -> id ; uint8_t scsicmd = cmd -> cmnd [ 0 ] ; if ( ( scsicmd == SYNCHRONIZE_CACHE ) || ( scsicmd == SEND_DIAGNOSTIC ) )  if ( target == 16 )  arcmsr_handle_virtual_command ( acb , cmd ); static void arcmsr_handle_virtual_command(struct AdapterControlBlock struct scsi_cmnd *cmd) switch ( cmd -> cmnd [ 0 ] )  if ( arcmsr_iop_message_xfer ( acb , cmd ) )  static int arcmsr_iop_message_xfer(struct AdapterControlBlock struct scsi_cmnd *cmd) char * buffer ; unsigned short use_sg ; int retvalue = 0 , transfer_len = 0 ; struct CMD_MESSAGE_FIELD * pcmdmessagefld ; uint32_t controlcode = ( uint32_t ) cmd -> cmnd [ 5 ] << 24 | ( uint32_t ) cmd -> cmnd [ 6 ] << 16 | ( uint32_t ) cmd -> cmnd [ 7 ] << 8 | ( uint32_t ) cmd -> cmnd [ 8 ] ; struct scatterlist * sg ; use_sg = scsi_sg_count ( cmd ); sg = scsi_sglist ( cmd ); buffer = kmap_atomic ( sg_page ( sg ) ) + sg -> offset; if ( use_sg > 1 )  transfer_len += sg -> length; if ( transfer_len > sizeof ( struct CMD_MESSAGE_FIELD ) )  pcmdmessagefld = ( struct CMD_MESSAGE_FIELD * ) buffer; switch ( controlcode )  unsigned char * ver_addr ; uint32_t allxfer_len = 0 ; ver_addr = kmalloc ( ARCMSR_API_DATA_BUFLEN , GFP_ATOMIC ); if ( ! ver_addr )  if ( acb -> rqbuf_getIndex != acb -> rqbuf_putIndex )  unsigned int tail = acb -> rqbuf_getIndex ; unsigned int head = acb -> rqbuf_putIndex ; allxfer_len = CIRC_CNT ( head , tail , ARCMSR_MAX_QBUFFER ); if ( allxfer_len > ARCMSR_API_DATA_BUFLEN )  allxfer_len = ARCMSR_API_DATA_BUFLEN; acb -> rqbuf_getIndex = ( acb -> rqbuf_getIndex + allxfer_len ) % ARCMSR_MAX_QBUFFER; memcpy ( pcmdmessagefld -> messagedatabuffer , ver_addr , allxfer_len ); if ( acb -> acb_flags & ACB_F_IOPDATA_OVERFLOW )  struct QBUFFER __iomem * prbuffer ; acb -> acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; prbuffer = arcmsr_get_iop_rqbuffer ( acb ); struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) struct QBUFFER __iomem * qbuffer = NULL ; switch ( acb -> adapter_type )  struct MessageUnit_A __iomem * reg = acb -> pmuA ; qbuffer = ( struct QBUFFER __iomem * ) & reg -> message_rbuffer; struct MessageUnit_B * reg = acb -> pmuB ; qbuffer = ( struct QBUFFER __iomem * ) reg -> message_rbuffer; struct MessageUnit_C __iomem * phbcmu = acb -> pmuC ; qbuffer = ( struct QBUFFER __iomem * ) & phbcmu -> message_rbuffer; struct MessageUnit_D * reg = acb -> pmuD ; qbuffer = ( struct QBUFFER __iomem * ) reg -> message_rbuffer; return qbuffer ; if ( arcmsr_Read_iop_rqbuffer_data ( acb , prbuffer ) == 0 )   arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock struct QBUFFER __iomem *prbuffer) if ( acb -> adapter_type & ( ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D ) )  return arcmsr_Read_iop_rqbuffer_in_DWORD ( acb , prbuffer ) ; static arcmsr_Read_iop_rqbuffer_in_DWORD(struct AdapterControlBlock struct QBUFFER __iomem *prbuffer) iop_len = readl ( & prbuffer -> data_len ); if ( iop_len > 0 )  buf1 = kmalloc ( 128 , GFP_ATOMIC ); if ( buf1 == NULL )  return 0 ; return 1 ; return 1 ; acb -> acb_flags |= ACB_F_IOPDATA_OVERFLOW; pcmdmessagefld -> cmdmessage . Length = allxfer_len; if ( acb -> fw_flag == FW_DEADLOCK )  pcmdmessagefld -> cmdmessage . ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; unsigned char * ver_addr ; int32_t user_len , cnt2end ; uint8_t * pQbuffer , * ptmpuserbuffer ; ver_addr = kmalloc ( ARCMSR_API_DATA_BUFLEN , GFP_ATOMIC ); if ( ! ver_addr )  ptmpuserbuffer = ver_addr; user_len = pcmdmessagefld -> cmdmessage . Length; memcpy ( ptmpuserbuffer , pcmdmessagefld -> messagedatabuffer , user_len ); if ( acb -> wqbuf_putIndex != acb -> wqbuf_getIndex )  pQbuffer = & acb -> wqbuffer [ acb -> wqbuf_putIndex ]; cnt2end = ARCMSR_MAX_QBUFFER - acb -> wqbuf_putIndex; if ( user_len > cnt2end )  memcpy ( pQbuffer , ptmpuserbuffer , cnt2end ); memcpy ( pQbuffer , ptmpuserbuffer , user_len ); 