Author: luporl
Date: Fri Jul 27 13:11:05 2018
New Revision: 336760
URL: https://svnweb.freebsd.org/changeset/base/336760

Log:
  Fixed endianess issue in AHCI driver
  
  There were some bits that were being set in cmd_flags (a field of AHCI's
  command list structure) after cmd_flags was converted to little endian.
  On a big endian host, such as PowerPC, this would set the wrong bits.
  This was preventing AHCI driver from working on these hosts.
  
  Reviewed by:  jhibbits
  Approved by:  jhibbits (mentor)

Modified:
  head/sys/dev/ahci/ahci.c

Modified: head/sys/dev/ahci/ahci.c
==============================================================================
--- head/sys/dev/ahci/ahci.c    Fri Jul 27 11:35:58 2018        (r336759)
+++ head/sys/dev/ahci/ahci.c    Fri Jul 27 13:11:05 2018        (r336760)
@@ -1523,6 +1523,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
        int fis_size, i, softreset;
        uint8_t *fis = ch->dma.rfis + 0x40;
        uint8_t val;
+       uint16_t cmd_flags;
 
        /* Get a piece of the workspace for this request */
        ctp = (struct ahci_cmd_tab *)
@@ -1536,12 +1537,12 @@ ahci_execute_transaction(struct ahci_slot *slot)
        /* Setup the command list entry */
        clp = (struct ahci_cmd_list *)
            (ch->dma.work + AHCI_CL_OFFSET + (AHCI_CL_SIZE * slot->slot));
-       clp->cmd_flags = htole16(
+       cmd_flags =
                    (ccb->ccb_h.flags & CAM_DIR_OUT ? AHCI_CMD_WRITE : 0) |
                    (ccb->ccb_h.func_code == XPT_SCSI_IO ?
                     (AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH) : 0) |
                    (fis_size / sizeof(u_int32_t)) |
-                   (port << 12));
+                   (port << 12);
        clp->prd_length = htole16(slot->dma.nsegs);
        /* Special handling for Soft Reset command. */
        if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
@@ -1552,7 +1553,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
                        ahci_stop(ch);
                        ahci_clo(ch);
                        ahci_start(ch, 0);
-                       clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY;
+                       cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY;
                } else {
                        softreset = 2;
                        /* Prepare FIS receive area for check. */
@@ -1562,6 +1563,7 @@ ahci_execute_transaction(struct ahci_slot *slot)
        } else
                softreset = 0;
        clp->bytecount = 0;
+       clp->cmd_flags = htole16(cmd_flags);
        clp->cmd_table_phys = htole64(ch->dma.work_bus + AHCI_CT_OFFSET +
                                  (AHCI_CT_SIZE * slot->slot));
        bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to