diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2011-06-02 00:07:31 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2011-06-02 00:07:31 +0000 |
commit | a4b5e250f35c4537603c860c7a1cfb2a06c3702a (patch) | |
tree | 1ccaedaaa211a8b268b4caa05e5420b8cf830645 | |
parent | 6fa12be07231784adc793eb02169167a7e701547 (diff) |
Small refactoring of atascsi and fix non-data ATA commands to not set
ATA_F_PIO or ATA_F_READ.
ok dlg@
-rw-r--r-- | sys/dev/ata/atascsi.c | 113 |
1 files changed, 65 insertions, 48 deletions
diff --git a/sys/dev/ata/atascsi.c b/sys/dev/ata/atascsi.c index bce24831d18..88e5d87644c 100644 --- a/sys/dev/ata/atascsi.c +++ b/sys/dev/ata/atascsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atascsi.c,v 1.105 2011/05/08 19:46:10 matthew Exp $ */ +/* $OpenBSD: atascsi.c,v 1.106 2011/06/02 00:07:30 matthew Exp $ */ /* * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> @@ -157,6 +157,11 @@ void *atascsi_io_get(void *); void atascsi_io_put(void *, void *); struct atascsi_port * atascsi_lookup_port(struct scsi_link *); +int atascsi_port_identify(struct atascsi_port *, + struct ata_identify *); +int atascsi_port_set_features(struct atascsi_port *, int, int); + + struct atascsi * atascsi_attach(struct device *self, struct atascsi_attach_args *aaa) { @@ -331,37 +336,23 @@ atascsi_probe(struct scsi_link *link) * identification from working, so we retry a few times * with a fairly long delay. */ + + identify = dma_alloc(sizeof(*identify), PR_WAITOK | PR_ZERO); + int count = (link->lun > 0) ? 6 : 1; while (count--) { - xa = scsi_io_get(&ahp->ahp_iopool, SCSI_NOSLEEP); - if (xa == NULL) - panic("no free xfers on a new port"); - identify = dma_alloc(sizeof(*identify), - PR_WAITOK | PR_ZERO); - xa->pmp_port = ap->ap_pmp_port; - xa->data = identify; - xa->datalen = sizeof(*identify); - xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; - xa->fis->command = (type == ATA_PORT_T_DISK) ? - ATA_C_IDENTIFY : ATA_C_IDENTIFY_PACKET; - xa->fis->device = 0; - xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL; - xa->timeout = 1000; - xa->complete = ata_polled_complete; - xa->atascsi_private = &ahp->ahp_iopool; - ata_exec(as, xa); - rv = ata_polled(xa); + rv = atascsi_port_identify(ap, identify); if (rv == 0) { bcopy(identify, &ap->ap_identify, sizeof(ap->ap_identify)); - dma_free(identify, sizeof(*identify)); break; } - dma_free(identify, sizeof(*identify)); if (count > 0) delay(5000000); } + dma_free(identify, sizeof(*identify)); + if (rv != 0) { goto error; } @@ -410,36 +401,14 @@ atascsi_probe(struct scsi_link *link) /* Enable write cache if supported */ if (ISSET(cmdset, ATA_IDENTIFY_WRITECACHE)) { - xa = scsi_io_get(&ahp->ahp_iopool, SCSI_NOSLEEP); - if (xa == NULL) - panic("no free xfers on a new port"); - xa->fis->command = ATA_C_SET_FEATURES; - xa->fis->features = ATA_SF_WRITECACHE_EN; - xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; - xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL; - xa->timeout = 1000; - xa->complete = ata_polled_complete; - xa->pmp_port = ap->ap_pmp_port; - xa->atascsi_private = &ahp->ahp_iopool; - ata_exec(as, xa); - ata_polled(xa); /* we dont care if it doesnt work */ + /* We don't care if it fails. */ + (void)atascsi_port_set_features(ap, ATA_SF_WRITECACHE_EN, 0); } /* Enable read lookahead if supported */ if (ISSET(cmdset, ATA_IDENTIFY_LOOKAHEAD)) { - xa = scsi_io_get(&ahp->ahp_iopool, SCSI_NOSLEEP); - if (xa == NULL) - panic("no free xfers on a new port"); - xa->fis->command = ATA_C_SET_FEATURES; - xa->fis->features = ATA_SF_LOOKAHEAD_EN; - xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; - xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL; - xa->timeout = 1000; - xa->complete = ata_polled_complete; - xa->pmp_port = ap->ap_pmp_port; - xa->atascsi_private = &ahp->ahp_iopool; - ata_exec(as, xa); - ata_polled(xa); /* we dont care if it doesnt work */ + /* We don't care if it fails. */ + (void)atascsi_port_set_features(ap, ATA_SF_LOOKAHEAD_EN, 0); } /* @@ -454,7 +423,7 @@ atascsi_probe(struct scsi_link *link) panic("no free xfers on a new port"); xa->fis->command = ATA_C_SEC_FREEZE_LOCK; xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; - xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL; + xa->flags = ATA_F_POLL; xa->timeout = 1000; xa->complete = ata_polled_complete; xa->pmp_port = ap->ap_pmp_port; @@ -1648,3 +1617,51 @@ ata_swapcopy(void *src, void *dst, size_t len) for (i = 0; i < len; i++) d[i] = swap16(s[i]); } + +int +atascsi_port_identify(struct atascsi_port *ap, struct ata_identify *identify) +{ + struct atascsi *as = ap->ap_as; + struct atascsi_host_port *ahp = ap->ap_host_port; + struct ata_xfer *xa; + + xa = scsi_io_get(&ahp->ahp_iopool, SCSI_NOSLEEP); + if (xa == NULL) + panic("no free xfers on a new port"); + xa->pmp_port = ap->ap_pmp_port; + xa->data = identify; + xa->datalen = sizeof(*identify); + xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; + xa->fis->command = (ap->ap_type == ATA_PORT_T_DISK) ? + ATA_C_IDENTIFY : ATA_C_IDENTIFY_PACKET; + xa->fis->device = 0; + xa->flags = ATA_F_READ | ATA_F_PIO | ATA_F_POLL; + xa->timeout = 1000; + xa->complete = ata_polled_complete; + xa->atascsi_private = &ahp->ahp_iopool; + ata_exec(as, xa); + return (ata_polled(xa)); +} + +int +atascsi_port_set_features(struct atascsi_port *ap, int subcommand, int arg) +{ + struct atascsi *as = ap->ap_as; + struct atascsi_host_port *ahp = ap->ap_host_port; + struct ata_xfer *xa; + + xa = scsi_io_get(&ahp->ahp_iopool, SCSI_NOSLEEP); + if (xa == NULL) + panic("no free xfers on a new port"); + xa->fis->command = ATA_C_SET_FEATURES; + xa->fis->features = subcommand; + xa->fis->sector_count = arg; + xa->fis->flags = ATA_H2D_FLAGS_CMD | ap->ap_pmp_port; + xa->flags = ATA_F_POLL; + xa->timeout = 1000; + xa->complete = ata_polled_complete; + xa->pmp_port = ap->ap_pmp_port; + xa->atascsi_private = &ahp->ahp_iopool; + ata_exec(as, xa); + return (ata_polled(xa)); +} |