diff options
| -rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 9caf9a979659..7b23f21f22f1 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
| @@ -185,6 +185,11 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) | |||
| 185 | if (crq->valid & 0x80) { | 185 | if (crq->valid & 0x80) { |
| 186 | if (++queue->cur == queue->size) | 186 | if (++queue->cur == queue->size) |
| 187 | queue->cur = 0; | 187 | queue->cur = 0; |
| 188 | |||
| 189 | /* Ensure the read of the valid bit occurs before reading any | ||
| 190 | * other bits of the CRQ entry | ||
| 191 | */ | ||
| 192 | rmb(); | ||
| 188 | } else | 193 | } else |
| 189 | crq = NULL; | 194 | crq = NULL; |
| 190 | spin_unlock_irqrestore(&queue->lock, flags); | 195 | spin_unlock_irqrestore(&queue->lock, flags); |
| @@ -203,6 +208,11 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, | |||
| 203 | { | 208 | { |
| 204 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 209 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
| 205 | 210 | ||
| 211 | /* | ||
| 212 | * Ensure the command buffer is flushed to memory before handing it | ||
| 213 | * over to the VIOS to prevent it from fetching any stale data. | ||
| 214 | */ | ||
| 215 | mb(); | ||
| 206 | return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); | 216 | return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); |
| 207 | } | 217 | } |
| 208 | 218 | ||
