hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/scsi/wd719x.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for Western Digital WD7193, WD7197 and WD7296 SCSI cards
34 * Copyright 2013 Ondrej Zary
....@@ -107,8 +108,15 @@
107108 }
108109
109110 if (status != WD719X_INT_NOERRORS) {
111
+ u8 sue = wd719x_readb(wd, WD719X_AMR_SCB_ERROR);
112
+ /* we get this after wd719x_dev_reset, it's not an error */
113
+ if (sue == WD719X_SUE_TERM)
114
+ return 0;
115
+ /* we get this after wd719x_bus_reset, it's not an error */
116
+ if (sue == WD719X_SUE_RESET)
117
+ return 0;
110118 dev_err(&wd->pdev->dev, "direct command failed, status 0x%02x, SUE 0x%02x\n",
111
- status, wd719x_readb(wd, WD719X_AMR_SCB_ERROR));
119
+ status, sue);
112120 return -EIO;
113121 }
114122
....@@ -127,8 +135,10 @@
127135 if (wd719x_wait_ready(wd))
128136 return -ETIMEDOUT;
129137
130
- /* make sure we get NO interrupts */
131
- dev |= WD719X_DISABLE_INT;
138
+ /* disable interrupts except for RESET/ABORT (it breaks them) */
139
+ if (opcode != WD719X_CMD_BUSRESET && opcode != WD719X_CMD_ABORT &&
140
+ opcode != WD719X_CMD_ABORT_TAG && opcode != WD719X_CMD_RESET)
141
+ dev |= WD719X_DISABLE_INT;
132142 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM, dev);
133143 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_2, lun);
134144 wd719x_writeb(wd, WD719X_AMR_CMD_PARAM_3, tag);
....@@ -153,8 +163,6 @@
153163
154164 static void wd719x_destroy(struct wd719x *wd)
155165 {
156
- struct wd719x_scb *scb;
157
-
158166 /* stop the RISC */
159167 if (wd719x_direct_cmd(wd, WD719X_CMD_SLEEP, 0, 0, 0, 0,
160168 WD719X_WAIT_FOR_RISC))
....@@ -162,37 +170,35 @@
162170 /* disable RISC */
163171 wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, 0);
164172
165
- /* free all SCBs */
166
- list_for_each_entry(scb, &wd->active_scbs, list)
167
- pci_free_consistent(wd->pdev, sizeof(struct wd719x_scb), scb,
168
- scb->phys);
169
- list_for_each_entry(scb, &wd->free_scbs, list)
170
- pci_free_consistent(wd->pdev, sizeof(struct wd719x_scb), scb,
171
- scb->phys);
173
+ WARN_ON_ONCE(!list_empty(&wd->active_scbs));
174
+
172175 /* free internal buffers */
173
- pci_free_consistent(wd->pdev, wd->fw_size, wd->fw_virt, wd->fw_phys);
176
+ dma_free_coherent(&wd->pdev->dev, wd->fw_size, wd->fw_virt,
177
+ wd->fw_phys);
174178 wd->fw_virt = NULL;
175
- pci_free_consistent(wd->pdev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
176
- wd->hash_phys);
179
+ dma_free_coherent(&wd->pdev->dev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
180
+ wd->hash_phys);
177181 wd->hash_virt = NULL;
178
- pci_free_consistent(wd->pdev, sizeof(struct wd719x_host_param),
179
- wd->params, wd->params_phys);
182
+ dma_free_coherent(&wd->pdev->dev, sizeof(struct wd719x_host_param),
183
+ wd->params, wd->params_phys);
180184 wd->params = NULL;
181185 free_irq(wd->pdev->irq, wd);
182186 }
183187
184
-/* finish a SCSI command, mark SCB (if any) as free, unmap buffers */
185
-static void wd719x_finish_cmd(struct scsi_cmnd *cmd, int result)
188
+/* finish a SCSI command, unmap buffers */
189
+static void wd719x_finish_cmd(struct wd719x_scb *scb, int result)
186190 {
191
+ struct scsi_cmnd *cmd = scb->cmd;
187192 struct wd719x *wd = shost_priv(cmd->device->host);
188
- struct wd719x_scb *scb = (struct wd719x_scb *) cmd->host_scribble;
189193
190
- if (scb) {
191
- list_move(&scb->list, &wd->free_scbs);
192
- dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
193
- SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
194
- scsi_dma_unmap(cmd);
195
- }
194
+ list_del(&scb->list);
195
+
196
+ dma_unmap_single(&wd->pdev->dev, scb->phys,
197
+ sizeof(struct wd719x_scb), DMA_BIDIRECTIONAL);
198
+ scsi_dma_unmap(cmd);
199
+ dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
200
+ SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
201
+
196202 cmd->result = result << 16;
197203 cmd->scsi_done(cmd);
198204 }
....@@ -202,36 +208,10 @@
202208 {
203209 int i, count_sg;
204210 unsigned long flags;
205
- struct wd719x_scb *scb;
211
+ struct wd719x_scb *scb = scsi_cmd_priv(cmd);
206212 struct wd719x *wd = shost_priv(sh);
207
- dma_addr_t phys;
208213
209
- cmd->host_scribble = NULL;
210
-
211
- /* get a free SCB - either from existing ones or allocate a new one */
212
- spin_lock_irqsave(wd->sh->host_lock, flags);
213
- scb = list_first_entry_or_null(&wd->free_scbs, struct wd719x_scb, list);
214
- if (scb) {
215
- list_del(&scb->list);
216
- phys = scb->phys;
217
- } else {
218
- spin_unlock_irqrestore(wd->sh->host_lock, flags);
219
- scb = pci_alloc_consistent(wd->pdev, sizeof(struct wd719x_scb),
220
- &phys);
221
- spin_lock_irqsave(wd->sh->host_lock, flags);
222
- if (!scb) {
223
- dev_err(&wd->pdev->dev, "unable to allocate SCB\n");
224
- wd719x_finish_cmd(cmd, DID_ERROR);
225
- spin_unlock_irqrestore(wd->sh->host_lock, flags);
226
- return 0;
227
- }
228
- }
229
- memset(scb, 0, sizeof(struct wd719x_scb));
230
- list_add(&scb->list, &wd->active_scbs);
231
-
232
- scb->phys = phys;
233214 scb->cmd = cmd;
234
- cmd->host_scribble = (char *) scb;
235215
236216 scb->CDB_tag = 0; /* Tagged queueing not supported yet */
237217 scb->devid = cmd->device->id;
....@@ -240,10 +220,19 @@
240220 /* copy the command */
241221 memcpy(scb->CDB, cmd->cmnd, cmd->cmd_len);
242222
223
+ /* map SCB */
224
+ scb->phys = dma_map_single(&wd->pdev->dev, scb, sizeof(*scb),
225
+ DMA_BIDIRECTIONAL);
226
+
227
+ if (dma_mapping_error(&wd->pdev->dev, scb->phys))
228
+ goto out_error;
229
+
243230 /* map sense buffer */
244231 scb->sense_buf_length = SCSI_SENSE_BUFFERSIZE;
245232 cmd->SCp.dma_handle = dma_map_single(&wd->pdev->dev, cmd->sense_buffer,
246233 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
234
+ if (dma_mapping_error(&wd->pdev->dev, cmd->SCp.dma_handle))
235
+ goto out_unmap_scb;
247236 scb->sense_buf = cpu_to_le32(cmd->SCp.dma_handle);
248237
249238 /* request autosense */
....@@ -258,11 +247,8 @@
258247
259248 /* Scather/gather */
260249 count_sg = scsi_dma_map(cmd);
261
- if (count_sg < 0) {
262
- wd719x_finish_cmd(cmd, DID_ERROR);
263
- spin_unlock_irqrestore(wd->sh->host_lock, flags);
264
- return 0;
265
- }
250
+ if (count_sg < 0)
251
+ goto out_unmap_sense;
266252 BUG_ON(count_sg > WD719X_SG);
267253
268254 if (count_sg) {
....@@ -283,11 +269,15 @@
283269 scb->data_p = 0;
284270 }
285271
272
+ spin_lock_irqsave(wd->sh->host_lock, flags);
273
+
286274 /* check if the Command register is free */
287275 if (wd719x_readb(wd, WD719X_AMR_COMMAND) != WD719X_CMD_READY) {
288276 spin_unlock_irqrestore(wd->sh->host_lock, flags);
289277 return SCSI_MLQUEUE_HOST_BUSY;
290278 }
279
+
280
+ list_add(&scb->list, &wd->active_scbs);
291281
292282 /* write pointer to the AMR */
293283 wd719x_writel(wd, WD719X_AMR_SCB_IN, scb->phys);
....@@ -295,7 +285,17 @@
295285 wd719x_writeb(wd, WD719X_AMR_COMMAND, WD719X_CMD_PROCESS_SCB);
296286
297287 spin_unlock_irqrestore(wd->sh->host_lock, flags);
288
+ return 0;
298289
290
+out_unmap_sense:
291
+ dma_unmap_single(&wd->pdev->dev, cmd->SCp.dma_handle,
292
+ SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
293
+out_unmap_scb:
294
+ dma_unmap_single(&wd->pdev->dev, scb->phys, sizeof(*scb),
295
+ DMA_BIDIRECTIONAL);
296
+out_error:
297
+ cmd->result = DID_ERROR << 16;
298
+ cmd->scsi_done(cmd);
299299 return 0;
300300 }
301301
....@@ -327,8 +327,8 @@
327327 wd->fw_size = ALIGN(fw_wcs->size, 4) + fw_risc->size;
328328
329329 if (!wd->fw_virt)
330
- wd->fw_virt = pci_alloc_consistent(wd->pdev, wd->fw_size,
331
- &wd->fw_phys);
330
+ wd->fw_virt = dma_alloc_coherent(&wd->pdev->dev, wd->fw_size,
331
+ &wd->fw_phys, GFP_KERNEL);
332332 if (!wd->fw_virt) {
333333 ret = -ENOMEM;
334334 goto wd719x_init_end;
....@@ -464,7 +464,7 @@
464464 {
465465 int action, result;
466466 unsigned long flags;
467
- struct wd719x_scb *scb = (struct wd719x_scb *)cmd->host_scribble;
467
+ struct wd719x_scb *scb = scsi_cmd_priv(cmd);
468468 struct wd719x *wd = shost_priv(cmd->device->host);
469469
470470 dev_info(&wd->pdev->dev, "abort command, tag: %x\n", cmd->tag);
....@@ -474,6 +474,7 @@
474474 spin_lock_irqsave(wd->sh->host_lock, flags);
475475 result = wd719x_direct_cmd(wd, action, cmd->device->id,
476476 cmd->device->lun, cmd->tag, scb->phys, 0);
477
+ wd719x_finish_cmd(scb, DID_ABORT);
477478 spin_unlock_irqrestore(wd->sh->host_lock, flags);
478479 if (result)
479480 return FAILED;
....@@ -486,6 +487,7 @@
486487 int result;
487488 unsigned long flags;
488489 struct wd719x *wd = shost_priv(cmd->device->host);
490
+ struct wd719x_scb *scb, *tmp;
489491
490492 dev_info(&wd->pdev->dev, "%s reset requested\n",
491493 (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device");
....@@ -493,6 +495,12 @@
493495 spin_lock_irqsave(wd->sh->host_lock, flags);
494496 result = wd719x_direct_cmd(wd, opcode, device, 0, 0, 0,
495497 WD719X_WAIT_FOR_SCSI_RESET);
498
+ /* flush all SCBs (or all for a device if dev_reset) */
499
+ list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list) {
500
+ if (opcode == WD719X_CMD_BUSRESET ||
501
+ scb->cmd->device->id == device)
502
+ wd719x_finish_cmd(scb, DID_RESET);
503
+ }
496504 spin_unlock_irqrestore(wd->sh->host_lock, flags);
497505 if (result)
498506 return FAILED;
....@@ -515,24 +523,23 @@
515523 struct wd719x *wd = shost_priv(cmd->device->host);
516524 struct wd719x_scb *scb, *tmp;
517525 unsigned long flags;
518
- int result;
519526
520527 dev_info(&wd->pdev->dev, "host reset requested\n");
521528 spin_lock_irqsave(wd->sh->host_lock, flags);
522
- /* Try to reinit the RISC */
523
- if (wd719x_chip_init(wd) == 0)
524
- result = SUCCESS;
525
- else
526
- result = FAILED;
529
+ /* stop the RISC */
530
+ if (wd719x_direct_cmd(wd, WD719X_CMD_SLEEP, 0, 0, 0, 0,
531
+ WD719X_WAIT_FOR_RISC))
532
+ dev_warn(&wd->pdev->dev, "RISC sleep command failed\n");
533
+ /* disable RISC */
534
+ wd719x_writeb(wd, WD719X_PCI_MODE_SELECT, 0);
527535
528536 /* flush all SCBs */
529
- list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list) {
530
- struct scsi_cmnd *tmp_cmd = scb->cmd;
531
- wd719x_finish_cmd(tmp_cmd, result);
532
- }
537
+ list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list)
538
+ wd719x_finish_cmd(scb, DID_RESET);
533539 spin_unlock_irqrestore(wd->sh->host_lock, flags);
534540
535
- return result;
541
+ /* Try to reinit the RISC */
542
+ return wd719x_chip_init(wd) == 0 ? SUCCESS : FAILED;
536543 }
537544
538545 static int wd719x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
....@@ -555,7 +562,6 @@
555562 union wd719x_regs regs,
556563 struct wd719x_scb *scb)
557564 {
558
- struct scsi_cmnd *cmd;
559565 int result;
560566
561567 /* now have to find result from card */
....@@ -643,9 +649,8 @@
643649 result = DID_ERROR;
644650 break;
645651 }
646
- cmd = scb->cmd;
647652
648
- wd719x_finish_cmd(cmd, result);
653
+ wd719x_finish_cmd(scb, result);
649654 }
650655
651656 static irqreturn_t wd719x_interrupt(int irq, void *dev_id)
....@@ -686,7 +691,7 @@
686691 else
687692 dev_err(&wd->pdev->dev, "card returned invalid SCB pointer\n");
688693 } else
689
- dev_warn(&wd->pdev->dev, "direct command 0x%x completed\n",
694
+ dev_dbg(&wd->pdev->dev, "direct command 0x%x completed\n",
690695 regs.bytes.OPC);
691696 break;
692697 case WD719X_INT_PIOREADY:
....@@ -809,7 +814,6 @@
809814 int ret;
810815
811816 INIT_LIST_HEAD(&wd->active_scbs);
812
- INIT_LIST_HEAD(&wd->free_scbs);
813817
814818 sh->base = pci_resource_start(wd->pdev, 0);
815819
....@@ -820,17 +824,18 @@
820824 wd->fw_virt = NULL;
821825
822826 /* memory area for host (EEPROM) parameters */
823
- wd->params = pci_alloc_consistent(wd->pdev,
824
- sizeof(struct wd719x_host_param),
825
- &wd->params_phys);
827
+ wd->params = dma_alloc_coherent(&wd->pdev->dev,
828
+ sizeof(struct wd719x_host_param),
829
+ &wd->params_phys, GFP_KERNEL);
826830 if (!wd->params) {
827831 dev_warn(&wd->pdev->dev, "unable to allocate parameter buffer\n");
828832 return -ENOMEM;
829833 }
830834
831835 /* memory area for the RISC for hash table of outstanding requests */
832
- wd->hash_virt = pci_alloc_consistent(wd->pdev, WD719X_HASH_TABLE_SIZE,
833
- &wd->hash_phys);
836
+ wd->hash_virt = dma_alloc_coherent(&wd->pdev->dev,
837
+ WD719X_HASH_TABLE_SIZE,
838
+ &wd->hash_phys, GFP_KERNEL);
834839 if (!wd->hash_virt) {
835840 dev_warn(&wd->pdev->dev, "unable to allocate hash buffer\n");
836841 ret = -ENOMEM;
....@@ -862,10 +867,10 @@
862867 fail_free_irq:
863868 free_irq(wd->pdev->irq, wd);
864869 fail_free_hash:
865
- pci_free_consistent(wd->pdev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
870
+ dma_free_coherent(&wd->pdev->dev, WD719X_HASH_TABLE_SIZE, wd->hash_virt,
866871 wd->hash_phys);
867872 fail_free_params:
868
- pci_free_consistent(wd->pdev, sizeof(struct wd719x_host_param),
873
+ dma_free_coherent(&wd->pdev->dev, sizeof(struct wd719x_host_param),
869874 wd->params, wd->params_phys);
870875
871876 return ret;
....@@ -874,6 +879,7 @@
874879 static struct scsi_host_template wd719x_template = {
875880 .module = THIS_MODULE,
876881 .name = "Western Digital 719x",
882
+ .cmd_size = sizeof(struct wd719x_scb),
877883 .queuecommand = wd719x_queuecommand,
878884 .eh_abort_handler = wd719x_abort,
879885 .eh_device_reset_handler = wd719x_dev_reset,
....@@ -884,7 +890,6 @@
884890 .can_queue = 255,
885891 .this_id = 7,
886892 .sg_tablesize = WD719X_SG,
887
- .use_clustering = ENABLE_CLUSTERING,
888893 };
889894
890895 static int wd719x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *d)
....@@ -897,7 +902,7 @@
897902 if (err)
898903 goto fail;
899904
900
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
905
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
901906 dev_warn(&pdev->dev, "Unable to set 32-bit DMA mask\n");
902907 goto disable_device;
903908 }