From owner-p4-projects@FreeBSD.ORG Sat Jun 13 14:23:12 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A27541065673; Sat, 13 Jun 2009 14:23:12 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 58D9C106564A for ; Sat, 13 Jun 2009 14:23:12 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 46A828FC12 for ; Sat, 13 Jun 2009 14:23:12 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5DENCFF066300 for ; Sat, 13 Jun 2009 14:23:12 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5DENClK066298 for perforce@freebsd.org; Sat, 13 Jun 2009 14:23:12 GMT (envelope-from mav@freebsd.org) Date: Sat, 13 Jun 2009 14:23:12 GMT Message-Id: <200906131423.n5DENClK066298@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Cc: Subject: PERFORCE change 164272 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jun 2009 14:23:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=164272 Change 164272 by mav@mav_mavbook on 2009/06/13 14:22:44 In preparation to PM support add flag that command require detailed status on successfull completion. Also make such command not to be queued by AHCI controller, as it is unable to report all results if several commands were completed on same interrupt. Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#8 edit .. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#8 edit .. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#15 edit .. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#24 edit .. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#11 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.c#8 (text+ko) ==== @@ -133,11 +133,11 @@ ataio->cmd.features_exp = sector_count >> 8; } -void ata_reset_cmd(struct ccb_ataio *ataio, int reset) +void ata_reset_cmd(struct ccb_ataio *ataio) { bzero(&ataio->cmd, sizeof(ataio->cmd)); - ataio->cmd.flags = CAM_ATAIO_CONTROL; - ataio->cmd.control = reset ? 0x04 : 0; + ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT; + ataio->cmd.control = 0x04; } #endif /* _KERNEL */ ==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_all.h#8 (text+ko) ==== @@ -38,6 +38,7 @@ #define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */ #define CAM_ATAIO_FPDMA 0x02 /* FPDMA command */ #define CAM_ATAIO_CONTROL 0x04 /* Control, not a command */ +#define CAM_ATAIO_NEEDRESULT 0x08 /* Request requires result. */ u_int8_t command; u_int8_t features; @@ -85,6 +86,6 @@ uint64_t lba, uint16_t sector_count); void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint64_t lba, uint16_t sector_count); -void ata_reset_cmd(struct ccb_ataio *ataio, int reset); +void ata_reset_cmd(struct ccb_ataio *ataio); #endif ==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_xpt.c#15 (text+ko) ==== @@ -336,7 +336,7 @@ /*data_ptr*/NULL, /*dxfer_len*/0, 30 * 1000); - ata_reset_cmd(ataio, 1); + ata_reset_cmd(ataio); break; case PROBE_IDENTIFY: { ==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#24 (text+ko) ==== @@ -904,11 +904,14 @@ return (1); } if ((ccb->ccb_h.func_code == XPT_ATA_IO) && - (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { - /* Control command while anything active. */ + (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) { + /* Atomic command while anything active. */ if (ch->numrslots != 0) return (1); } + /* We have some atomic command running. */ + if (ch->aslots != 0) + return (1); return (0); } @@ -938,11 +941,14 @@ slot->ccb = ccb; /* Update channel stats. */ ch->numrslots++; - if ((slot->ccb->ccb_h.func_code == XPT_ATA_IO) && - (slot->ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots++; ch->taggedtarget = ccb->ccb_h.target_id; } + if ((ccb->ccb_h.func_code == XPT_ATA_IO) && + (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) + ch->aslots |= (1 << slot->slot); slot->dma.nsegs = 0; /* If request moves data, setup and load SG list */ if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { @@ -1030,7 +1036,7 @@ /* Special handling for Soft Reset command. */ if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && - ccb->ataio.cmd.control & ATA_A_RESET) { + (ccb->ataio.cmd.control & ATA_A_RESET)) { /* Kick controller into sane state */ ahci_stop(dev); ahci_clo(dev); @@ -1151,8 +1157,8 @@ if (ccb->ccb_h.func_code == XPT_ATA_IO) { struct ata_res *res = &ccb->ataio.res; - if (et == AHCI_ERR_REAL || - ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) { + if ((et == AHCI_ERR_REAL) || + (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) { u_int8_t *fis = ch->dma.rfis + 0x40; bus_dmamap_sync(ch->dma.rfis_tag, ch->dma.rfis_map, @@ -1209,6 +1215,7 @@ } /* Free slot. */ ch->rslots &= ~(1 << slot->slot); + ch->aslots &= ~(1 << slot->slot); slot->state = AHCI_SLOT_EMPTY; slot->ccb = NULL; /* Update channel stats. */ @@ -1217,8 +1224,8 @@ (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) { ch->numtslots--; } - /* If it was first request of reset sequence nod no error, - * proceed to second. */ + /* If it was first request of reset sequence and there is no error, + * proceed to second request. */ if ((ccb->ccb_h.func_code == XPT_ATA_IO) && (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) && (ccb->ataio.cmd.control & ATA_A_RESET) && @@ -1233,11 +1240,7 @@ //device_printf(dev, "Unfreeze\n"); ch->frozen = NULL; ahci_begin_transaction(dev, fccb); - /* If frozen command is not reset - release queue. - * Reset will be released after it is finished. */ - if ((fccb->ccb_h.func_code == XPT_ATA_IO) && - (fccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) - xpt_release_simq(ch->sim, TRUE); + xpt_release_simq(ch->sim, TRUE); } } @@ -1534,19 +1537,13 @@ } /* Check for command collision. */ if (ahci_check_collision(dev, ccb)) { +//device_printf(dev, "Freeze\n"); /* Freeze command. */ -//device_printf(dev, "Freeze\n"); + ch->frozen = ccb; /* We have only one frozen slot, so freeze simq also. */ xpt_freeze_simq(ch->sim, 1); - ch->frozen = ccb; return; } - /* If it is a reset sequence - freeze the queue. */ - if ((ccb->ccb_h.func_code == XPT_ATA_IO) && - (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) { - xpt_freeze_simq(ch->sim, 1); - ccb->ccb_h.status |= CAM_RELEASE_SIMQ; - } ahci_begin_transaction(dev, ccb); break; case XPT_EN_LUN: /* Enable LUN as a target */ ==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#11 (text+ko) ==== @@ -343,6 +343,7 @@ struct mtx mtx; /* state lock */ int devices; /* What is present */ uint32_t rslots; /* Running slots */ + uint32_t aslots; /* Slots with atomic commands */ int numrslots; /* Number of running slots */ int numtslots; /* Number of tagged slots */ int lastslot; /* Last used slot */