diff options
author | Tejun Heo <htejun@gmail.com> | 2006-01-22 23:09:36 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-26 22:33:49 -0500 |
commit | 77853bf2b48e34449e826a9ef4df5ea0dbe947f4 (patch) | |
tree | b46a186c141c61f05352b7a1199b2940fd9a2065 /drivers | |
parent | 4ba946e9d8e10fada7bbce527f6ea05842592e06 (diff) |
[PATCH] libata: make the owner of a qc responsible for freeing it
qc used to be freed automatically on command completion. However, as
a qc can carry information about its completion status, it can be
useful to its owner/issuer after command completion. This patch makes
freeing qc responsibility of its owner. This simplifies
ata_exec_internal() and makes command turn-around for atapi request
sensing less hackish.
This change was originally suggested by Jeff Garzik.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/libata-core.c | 47 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 14 |
2 files changed, 20 insertions, 41 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0e4932362949..15df633521d0 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1072,24 +1072,12 @@ static unsigned int ata_pio_modes(const struct ata_device *adev) | |||
1072 | timing API will get this right anyway */ | 1072 | timing API will get this right anyway */ |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | struct ata_exec_internal_arg { | 1075 | void ata_qc_complete_internal(struct ata_queued_cmd *qc) |
1076 | unsigned int err_mask; | ||
1077 | struct ata_taskfile *tf; | ||
1078 | struct completion *waiting; | ||
1079 | }; | ||
1080 | |||
1081 | int ata_qc_complete_internal(struct ata_queued_cmd *qc) | ||
1082 | { | 1076 | { |
1083 | struct ata_exec_internal_arg *arg = qc->private_data; | 1077 | struct completion *waiting = qc->private_data; |
1084 | struct completion *waiting = arg->waiting; | ||
1085 | 1078 | ||
1086 | if (!(qc->err_mask & ~AC_ERR_DEV)) | 1079 | qc->ap->ops->tf_read(qc->ap, &qc->tf); |
1087 | qc->ap->ops->tf_read(qc->ap, arg->tf); | ||
1088 | arg->err_mask = qc->err_mask; | ||
1089 | arg->waiting = NULL; | ||
1090 | complete(waiting); | 1080 | complete(waiting); |
1091 | |||
1092 | return 0; | ||
1093 | } | 1081 | } |
1094 | 1082 | ||
1095 | /** | 1083 | /** |
@@ -1120,7 +1108,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, | |||
1120 | struct ata_queued_cmd *qc; | 1108 | struct ata_queued_cmd *qc; |
1121 | DECLARE_COMPLETION(wait); | 1109 | DECLARE_COMPLETION(wait); |
1122 | unsigned long flags; | 1110 | unsigned long flags; |
1123 | struct ata_exec_internal_arg arg; | 1111 | unsigned int err_mask; |
1124 | 1112 | ||
1125 | spin_lock_irqsave(&ap->host_set->lock, flags); | 1113 | spin_lock_irqsave(&ap->host_set->lock, flags); |
1126 | 1114 | ||
@@ -1134,9 +1122,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, | |||
1134 | qc->nsect = buflen / ATA_SECT_SIZE; | 1122 | qc->nsect = buflen / ATA_SECT_SIZE; |
1135 | } | 1123 | } |
1136 | 1124 | ||
1137 | arg.waiting = &wait; | 1125 | qc->private_data = &wait; |
1138 | arg.tf = tf; | ||
1139 | qc->private_data = &arg; | ||
1140 | qc->complete_fn = ata_qc_complete_internal; | 1126 | qc->complete_fn = ata_qc_complete_internal; |
1141 | 1127 | ||
1142 | if (ata_qc_issue(qc)) | 1128 | if (ata_qc_issue(qc)) |
@@ -1153,7 +1139,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, | |||
1153 | * before the caller cleans up, it will result in a | 1139 | * before the caller cleans up, it will result in a |
1154 | * spurious interrupt. We can live with that. | 1140 | * spurious interrupt. We can live with that. |
1155 | */ | 1141 | */ |
1156 | if (arg.waiting) { | 1142 | if (qc->flags & ATA_QCFLAG_ACTIVE) { |
1157 | qc->err_mask = AC_ERR_OTHER; | 1143 | qc->err_mask = AC_ERR_OTHER; |
1158 | ata_qc_complete(qc); | 1144 | ata_qc_complete(qc); |
1159 | printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", | 1145 | printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", |
@@ -1163,7 +1149,12 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, | |||
1163 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 1149 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
1164 | } | 1150 | } |
1165 | 1151 | ||
1166 | return arg.err_mask; | 1152 | *tf = qc->tf; |
1153 | err_mask = qc->err_mask; | ||
1154 | |||
1155 | ata_qc_free(qc); | ||
1156 | |||
1157 | return err_mask; | ||
1167 | 1158 | ||
1168 | issue_fail: | 1159 | issue_fail: |
1169 | ata_qc_free(qc); | 1160 | ata_qc_free(qc); |
@@ -3633,8 +3624,6 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
3633 | 3624 | ||
3634 | void ata_qc_complete(struct ata_queued_cmd *qc) | 3625 | void ata_qc_complete(struct ata_queued_cmd *qc) |
3635 | { | 3626 | { |
3636 | int rc; | ||
3637 | |||
3638 | assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ | 3627 | assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ |
3639 | assert(qc->flags & ATA_QCFLAG_ACTIVE); | 3628 | assert(qc->flags & ATA_QCFLAG_ACTIVE); |
3640 | 3629 | ||
@@ -3648,17 +3637,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc) | |||
3648 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | 3637 | qc->flags &= ~ATA_QCFLAG_ACTIVE; |
3649 | 3638 | ||
3650 | /* call completion callback */ | 3639 | /* call completion callback */ |
3651 | rc = qc->complete_fn(qc); | 3640 | qc->complete_fn(qc); |
3652 | |||
3653 | /* if callback indicates not to complete command (non-zero), | ||
3654 | * return immediately | ||
3655 | */ | ||
3656 | if (rc != 0) | ||
3657 | return; | ||
3658 | |||
3659 | ata_qc_free(qc); | ||
3660 | |||
3661 | VPRINTK("EXIT\n"); | ||
3662 | } | 3641 | } |
3663 | 3642 | ||
3664 | static inline int ata_should_dma_map(struct ata_queued_cmd *qc) | 3643 | static inline int ata_should_dma_map(struct ata_queued_cmd *qc) |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 0e65bfe92e6f..ce3fe928a386 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -1219,7 +1219,7 @@ nothing_to_do: | |||
1219 | return 1; | 1219 | return 1; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) | 1222 | static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) |
1223 | { | 1223 | { |
1224 | struct scsi_cmnd *cmd = qc->scsicmd; | 1224 | struct scsi_cmnd *cmd = qc->scsicmd; |
1225 | u8 *cdb = cmd->cmnd; | 1225 | u8 *cdb = cmd->cmnd; |
@@ -1256,7 +1256,7 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) | |||
1256 | 1256 | ||
1257 | qc->scsidone(cmd); | 1257 | qc->scsidone(cmd); |
1258 | 1258 | ||
1259 | return 0; | 1259 | ata_qc_free(qc); |
1260 | } | 1260 | } |
1261 | 1261 | ||
1262 | /** | 1262 | /** |
@@ -1982,7 +1982,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 | |||
1982 | done(cmd); | 1982 | done(cmd); |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | static int atapi_sense_complete(struct ata_queued_cmd *qc) | 1985 | static void atapi_sense_complete(struct ata_queued_cmd *qc) |
1986 | { | 1986 | { |
1987 | if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) | 1987 | if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) |
1988 | /* FIXME: not quite right; we don't want the | 1988 | /* FIXME: not quite right; we don't want the |
@@ -1993,7 +1993,7 @@ static int atapi_sense_complete(struct ata_queued_cmd *qc) | |||
1993 | ata_gen_ata_desc_sense(qc); | 1993 | ata_gen_ata_desc_sense(qc); |
1994 | 1994 | ||
1995 | qc->scsidone(qc->scsicmd); | 1995 | qc->scsidone(qc->scsicmd); |
1996 | return 0; | 1996 | ata_qc_free(qc); |
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | /* is it pointless to prefer PIO for "safety reasons"? */ | 1999 | /* is it pointless to prefer PIO for "safety reasons"? */ |
@@ -2050,7 +2050,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) | |||
2050 | DPRINTK("EXIT\n"); | 2050 | DPRINTK("EXIT\n"); |
2051 | } | 2051 | } |
2052 | 2052 | ||
2053 | static int atapi_qc_complete(struct ata_queued_cmd *qc) | 2053 | static void atapi_qc_complete(struct ata_queued_cmd *qc) |
2054 | { | 2054 | { |
2055 | struct scsi_cmnd *cmd = qc->scsicmd; | 2055 | struct scsi_cmnd *cmd = qc->scsicmd; |
2056 | unsigned int err_mask = qc->err_mask; | 2056 | unsigned int err_mask = qc->err_mask; |
@@ -2060,7 +2060,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc) | |||
2060 | if (unlikely(err_mask & AC_ERR_DEV)) { | 2060 | if (unlikely(err_mask & AC_ERR_DEV)) { |
2061 | cmd->result = SAM_STAT_CHECK_CONDITION; | 2061 | cmd->result = SAM_STAT_CHECK_CONDITION; |
2062 | atapi_request_sense(qc); | 2062 | atapi_request_sense(qc); |
2063 | return 1; | 2063 | return; |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | else if (unlikely(err_mask)) | 2066 | else if (unlikely(err_mask)) |
@@ -2100,7 +2100,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc) | |||
2100 | } | 2100 | } |
2101 | 2101 | ||
2102 | qc->scsidone(cmd); | 2102 | qc->scsidone(cmd); |
2103 | return 0; | 2103 | ata_qc_free(qc); |
2104 | } | 2104 | } |
2105 | /** | 2105 | /** |
2106 | * atapi_xlat - Initialize PACKET taskfile | 2106 | * atapi_xlat - Initialize PACKET taskfile |