svn commit: r268815 - stable/10/sys/cam/ata
Warner Losh
imp at FreeBSD.org
Thu Jul 17 22:58:06 UTC 2014
Author: imp
Date: Thu Jul 17 22:58:05 2014
New Revision: 268815
URL: http://svnweb.freebsd.org/changeset/base/268815
Log:
MFC:
>r268205 | imp | 2014-07-02 23:22:13 -0600 (Wed, 02 Jul 2014) | 9 lines
>Rework the BIO_DELETE code slightly. Always queue the BIO_DELETE
>requests on the trim_queue, even for the CFA ERASE. This allows us, in
>the future, to collapse adjacent requests. Since CFA ERASE is only for
>CF cards, and it is so restrictive in what it can do, the collapse
>code is not presently here. This also brings the ada driver more in
>line with the da driver's treatment of BIO_DELETEs.
Modified:
stable/10/sys/cam/ata/ata_da.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/cam/ata/ata_da.c
==============================================================================
--- stable/10/sys/cam/ata/ata_da.c Thu Jul 17 22:42:18 2014 (r268814)
+++ stable/10/sys/cam/ata/ata_da.c Thu Jul 17 22:58:05 2014 (r268815)
@@ -727,8 +727,11 @@ adastrategy(struct bio *bp)
/*
* Place it in the queue of disk activities for this disk
*/
- if (bp->bio_cmd == BIO_DELETE &&
- (softc->flags & ADA_FLAG_CAN_TRIM)) {
+ if (bp->bio_cmd == BIO_DELETE) {
+ KASSERT((softc->flags & ADA_FLAG_CAN_TRIM) ||
+ ((softc->flags & ADA_FLAG_CAN_CFA) &&
+ !(softc->flags & ADA_FLAG_CAN_48BIT)),
+ ("BIO_DELETE but no supported TRIM method."));
if (ADA_SIO)
bioq_disksort(&softc->trim_queue, bp);
else
@@ -1386,6 +1389,96 @@ adaregister(struct cam_periph *periph, v
}
static void
+ada_dsmtrim(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
+{
+ struct trim_request *req = &softc->trim_req;
+ uint64_t lastlba = (uint64_t)-1;
+ int c, lastcount = 0, off, ranges = 0;
+
+ bzero(req, sizeof(*req));
+ TAILQ_INIT(&req->bps);
+ do {
+ uint64_t lba = bp->bio_pblkno;
+ int count = bp->bio_bcount / softc->params.secsize;
+
+ bioq_remove(&softc->trim_queue, bp);
+
+ /* Try to extend the previous range. */
+ if (lba == lastlba) {
+ c = min(count, ATA_DSM_RANGE_MAX - lastcount);
+ lastcount += c;
+ off = (ranges - 1) * ATA_DSM_RANGE_SIZE;
+ req->data[off + 6] = lastcount & 0xff;
+ req->data[off + 7] =
+ (lastcount >> 8) & 0xff;
+ count -= c;
+ lba += c;
+ }
+
+ while (count > 0) {
+ c = min(count, ATA_DSM_RANGE_MAX);
+ off = ranges * ATA_DSM_RANGE_SIZE;
+ req->data[off + 0] = lba & 0xff;
+ req->data[off + 1] = (lba >> 8) & 0xff;
+ req->data[off + 2] = (lba >> 16) & 0xff;
+ req->data[off + 3] = (lba >> 24) & 0xff;
+ req->data[off + 4] = (lba >> 32) & 0xff;
+ req->data[off + 5] = (lba >> 40) & 0xff;
+ req->data[off + 6] = c & 0xff;
+ req->data[off + 7] = (c >> 8) & 0xff;
+ lba += c;
+ count -= c;
+ lastcount = c;
+ ranges++;
+ /*
+ * Its the caller's responsibility to ensure the
+ * request will fit so we don't need to check for
+ * overrun here
+ */
+ }
+ lastlba = lba;
+ TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
+ bp = bioq_first(&softc->trim_queue);
+ if (bp == NULL ||
+ bp->bio_bcount / softc->params.secsize >
+ (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX)
+ break;
+ } while (1);
+ cam_fill_ataio(ataio,
+ ada_retry_count,
+ adadone,
+ CAM_DIR_OUT,
+ 0,
+ req->data,
+ ((ranges + ATA_DSM_BLK_RANGES - 1) /
+ ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
+ ada_default_timeout * 1000);
+ ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
+ ATA_DSM_TRIM, 0, (ranges + ATA_DSM_BLK_RANGES -
+ 1) / ATA_DSM_BLK_RANGES);
+}
+
+static void
+ada_cfaerase(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
+{
+ uint64_t lba = bp->bio_pblkno;
+ uint16_t count = bp->bio_bcount / softc->params.secsize;
+
+ cam_fill_ataio(ataio,
+ ada_retry_count,
+ adadone,
+ CAM_DIR_NONE,
+ 0,
+ NULL,
+ 0,
+ ada_default_timeout*1000);
+
+ if (count >= 256)
+ count = 0;
+ ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
+}
+
+static void
adastart(struct cam_periph *periph, union ccb *start_ccb)
{
struct ada_softc *softc = (struct ada_softc *)periph->softc;
@@ -1402,76 +1495,15 @@ adastart(struct cam_periph *periph, unio
/* Run TRIM if not running yet. */
if (!softc->trim_running &&
(bp = bioq_first(&softc->trim_queue)) != 0) {
- struct trim_request *req = &softc->trim_req;
- struct bio *bp1;
- uint64_t lastlba = (uint64_t)-1;
- int c, lastcount = 0, off, ranges = 0;
-
+ if (softc->flags & ADA_FLAG_CAN_TRIM) {
+ ada_dsmtrim(softc, bp, ataio);
+ } else if ((softc->flags & ADA_FLAG_CAN_CFA) &&
+ !(softc->flags & ADA_FLAG_CAN_48BIT)) {
+ ada_cfaerase(softc, bp, ataio);
+ } else {
+ panic("adastart: BIO_DELETE without method, not possible.");
+ }
softc->trim_running = 1;
- bzero(req, sizeof(*req));
- TAILQ_INIT(&req->bps);
- bp1 = bp;
- do {
- uint64_t lba = bp1->bio_pblkno;
- int count = bp1->bio_bcount /
- softc->params.secsize;
-
- bioq_remove(&softc->trim_queue, bp1);
-
- /* Try to extend the previous range. */
- if (lba == lastlba) {
- c = min(count, ATA_DSM_RANGE_MAX - lastcount);
- lastcount += c;
- off = (ranges - 1) * ATA_DSM_RANGE_SIZE;
- req->data[off + 6] = lastcount & 0xff;
- req->data[off + 7] =
- (lastcount >> 8) & 0xff;
- count -= c;
- lba += c;
- }
-
- while (count > 0) {
- c = min(count, ATA_DSM_RANGE_MAX);
- off = ranges * ATA_DSM_RANGE_SIZE;
- req->data[off + 0] = lba & 0xff;
- req->data[off + 1] = (lba >> 8) & 0xff;
- req->data[off + 2] = (lba >> 16) & 0xff;
- req->data[off + 3] = (lba >> 24) & 0xff;
- req->data[off + 4] = (lba >> 32) & 0xff;
- req->data[off + 5] = (lba >> 40) & 0xff;
- req->data[off + 6] = c & 0xff;
- req->data[off + 7] = (c >> 8) & 0xff;
- lba += c;
- count -= c;
- lastcount = c;
- ranges++;
- /*
- * Its the caller's responsibility to ensure the
- * request will fit so we don't need to check for
- * overrun here
- */
- }
- lastlba = lba;
- TAILQ_INSERT_TAIL(&req->bps, bp1, bio_queue);
- bp1 = bioq_first(&softc->trim_queue);
- if (bp1 == NULL ||
- bp1->bio_bcount / softc->params.secsize >
- (softc->trim_max_ranges - ranges) *
- ATA_DSM_RANGE_MAX)
- break;
- } while (1);
- cam_fill_ataio(ataio,
- ada_retry_count,
- adadone,
- CAM_DIR_OUT,
- 0,
- req->data,
- ((ranges + ATA_DSM_BLK_RANGES - 1) /
- ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
- ada_default_timeout * 1000);
- ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
- ATA_DSM_TRIM, 0, (ranges + ATA_DSM_BLK_RANGES -
- 1) / ATA_DSM_BLK_RANGES);
start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
start_ccb->ccb_h.flags |= CAM_UNLOCKED;
goto out;
@@ -1606,25 +1638,6 @@ adastart(struct cam_periph *periph, unio
}
break;
}
- case BIO_DELETE:
- {
- uint64_t lba = bp->bio_pblkno;
- uint16_t count = bp->bio_bcount / softc->params.secsize;
-
- cam_fill_ataio(ataio,
- ada_retry_count,
- adadone,
- CAM_DIR_NONE,
- 0,
- NULL,
- 0,
- ada_default_timeout*1000);
-
- if (count >= 256)
- count = 0;
- ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
- break;
- }
case BIO_FLUSH:
cam_fill_ataio(ataio,
1,
More information about the svn-src-stable-10
mailing list