func: static void megasas_mmio_write(void *opaque, hwaddr uint64_t val, unsigned size) MegasasState * s = opaque ; uint64_t frame_addr ; uint32_t frame_count ; switch ( addr )  if ( val & MFI_FWINIT_STOP_ADP )  s -> fw_state = MFI_FWSTATE_FAULT; s -> intr_mask = val; s -> doorbell = 0; s -> frame_hi = val; if ( addr == MFI_IQP )  s -> frame_hi = 0; frame_addr = ( val & ~0x1F ); frame_addr |= ( ( uint64_t ) s -> frame_hi << 32 ); s -> frame_hi = 0; frame_count = ( val >> 1 ) & 0xF; megasas_handle_frame ( s , frame_addr , frame_count ); static void megasas_handle_frame(MegasasState *s, uint64_t uint32_t frame_count) uint64_t frame_context ; MegasasCmd * cmd ; frame_context = megasas_frame_get_context ( s , frame_addr ); cmd = megasas_enqueue_frame ( s , frame_addr , frame_context , frame_count ); static MegasasCmd *megasas_enqueue_frame(MegasasState hwaddr frame, uint64_t context, int count) PCIDevice * pcid = PCI_DEVICE ( s ) ; int frame_size = MFI_FRAME_SIZE * 16 ; hwaddr frame_size_p = frame_size ; unsigned long index ; index = 0; while ( index < s -> fw_cmds )  index = find_next_zero_bit ( s -> frame_map , s -> fw_cmds , index ); if ( ! s -> frames [ index ] . pa )  if ( index >= s -> fw_cmds )  return NULL ; cmd = & s -> frames [ index ]; cmd -> pa = frame; cmd -> frame = pci_dma_map ( pcid , frame , & frame_size_p , 0 ); if ( frame_size_p != frame_size )  return NULL ; cmd -> pa_size = frame_size_p; cmd -> context = context; if ( ! megasas_use_queue64 ( s ) )  static bool megasas_use_queue64(MegasasState *s) return s -> flags & MEGASAS_MASK_USE_QUEUE64 ; cmd -> context &= ( uint64_t ) 0xFFFFFFFF; cmd -> count = count; return cmd ; if ( ! cmd )  switch ( cmd -> frame -> header . frame_cmd )  frame_status = megasas_handle_io ( s , cmd ); static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd) uint32_t lba_count , lba_start_hi , lba_start_lo ; uint64_t lba_start ; bool is_write = ( cmd -> frame -> header . frame_cmd == MFI_CMD_LD_WRITE ) ; uint8_t cdb [ 16 ] ; struct SCSIDevice * sdev = NULL ; lba_count = le32_to_cpu ( cmd -> frame -> io . header . data_len ); lba_start_lo = le32_to_cpu ( cmd -> frame -> io . lba_lo ); lba_start_hi = le32_to_cpu ( cmd -> frame -> io . lba_hi ); lba_start = ( ( uint64_t ) lba_start_hi << 32 ) | lba_start_lo; if ( cmd -> frame -> header . target_id < MFI_MAX_LD && cmd -> frame -> header . lun_id == 0 )  sdev = scsi_device_find ( & s -> bus , 0 , cmd -> frame -> header . target_id , cmd -> frame -> header . lun_id ); if ( ! sdev )  if ( cmd -> frame -> header . cdb_len > 16 )  cmd -> iov_size = lba_count * sdev -> blocksize; if ( megasas_map_sgl ( s , cmd , & cmd -> frame -> io . sgl ) )  static int megasas_map_sgl(MegasasState *s, MegasasCmd *cmd, union mfi_sgl *sgl) int i ; cmd -> flags = le16_to_cpu ( cmd -> frame -> header . flags ); iov_count = cmd -> frame -> header . sge_count; if ( iov_count > MEGASAS_MAX_SGE )  return iov_count ; for (i = 0; i < iov_count; i++) dma_addr_t iov_pa , iov_size_p ; if ( ! sgl )  iov_pa = megasas_sgl_get_addr ( cmd , sgl ); static uint64_t megasas_sgl_get_addr(MegasasCmd union mfi_sgl *sgl) uint64_t addr ; if ( megasas_frame_is_ieee_sgl ( cmd ) )  static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_IEEE_SGL ; addr = le64_to_cpu ( sgl -> sg_skinny -> addr ); if ( megasas_frame_is_sgl64 ( cmd ) )  static bool megasas_frame_is_sgl64(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_SGL64 ; addr = le64_to_cpu ( sgl -> sg64 -> addr ); addr = le32_to_cpu ( sgl -> sg32 -> addr ); return addr ; iov_size_p = megasas_sgl_get_len ( cmd , sgl ); static uint32_t megasas_sgl_get_len(MegasasCmd union mfi_sgl *sgl) uint32_t len ; if ( megasas_frame_is_ieee_sgl ( cmd ) )  static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_IEEE_SGL ; len = le32_to_cpu ( sgl -> sg_skinny -> len ); if ( megasas_frame_is_sgl64 ( cmd ) )  static bool megasas_frame_is_sgl64(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_SGL64 ; len = le32_to_cpu ( sgl -> sg64 -> len ); len = le32_to_cpu ( sgl -> sg32 -> len ); return len ; if ( ! iov_pa || ! iov_size_p )  sgl = megasas_sgl_next ( cmd , sgl ); static union mfi_sgl *megasas_sgl_next(MegasasCmd union mfi_sgl *sgl) uint8_t * next = ( uint8_t * ) sgl ; if ( megasas_frame_is_ieee_sgl ( cmd ) )  static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_IEEE_SGL ; next += sizeof ( struct mfi_sg_skinny ); if ( megasas_frame_is_sgl64 ( cmd ) )  static bool megasas_frame_is_sgl64(MegasasCmd *cmd) return cmd -> flags & MFI_FRAME_SGL64 ; next += sizeof ( struct mfi_sg64 ); next += sizeof ( struct mfi_sg32 ); if ( next >= ( uint8_t * ) cmd -> frame + cmd -> pa_size )  return NULL ; return ( union mfi_sgl * ) next ; return 0 ; return iov_count - i ; megasas_encode_lba ( cdb , lba_start , lba_count , is_write ); static void megasas_encode_lba(uint8_t *cdb, uint64_t uint32_t len, bool is_write) memset ( cdb , 0x0 , 16 ); cdb [ 0 ] = WRITE_16; 