hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/scsi/53c700.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* -*- mode: c; c-basic-offset: 8 -*- */
23
34 /* NCR (or Symbios) 53c700 and 53c700-66 Driver
....@@ -5,19 +6,6 @@
56 * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
67 **-----------------------------------------------------------------------------
78 **
8
-** This program is free software; you can redistribute it and/or modify
9
-** it under the terms of the GNU General Public License as published by
10
-** the Free Software Foundation; either version 2 of the License, or
11
-** (at your option) any later version.
12
-**
13
-** This program is distributed in the hope that it will be useful,
14
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
-** GNU General Public License for more details.
17
-**
18
-** You should have received a copy of the GNU General Public License
19
-** along with this program; if not, write to the Free Software
20
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
219 **
2210 **-----------------------------------------------------------------------------
2311 */
....@@ -128,9 +116,9 @@
128116 #include <linux/module.h>
129117 #include <linux/interrupt.h>
130118 #include <linux/device.h>
119
+#include <linux/pgtable.h>
131120 #include <asm/dma.h>
132121 #include <asm/io.h>
133
-#include <asm/pgtable.h>
134122 #include <asm/byteorder.h>
135123
136124 #include <scsi/scsi.h>
....@@ -281,6 +269,27 @@
281269 spi_period(SDp->sdev_target));
282270 }
283271
272
+static inline dma_addr_t virt_to_dma(struct NCR_700_Host_Parameters *h, void *p)
273
+{
274
+ return h->pScript + ((uintptr_t)p - (uintptr_t)h->script);
275
+}
276
+
277
+static inline void dma_sync_to_dev(struct NCR_700_Host_Parameters *h,
278
+ void *addr, size_t size)
279
+{
280
+ if (h->noncoherent)
281
+ dma_sync_single_for_device(h->dev, virt_to_dma(h, addr),
282
+ size, DMA_BIDIRECTIONAL);
283
+}
284
+
285
+static inline void dma_sync_from_dev(struct NCR_700_Host_Parameters *h,
286
+ void *addr, size_t size)
287
+{
288
+ if (h->noncoherent)
289
+ dma_sync_single_for_device(h->dev, virt_to_dma(h, addr), size,
290
+ DMA_BIDIRECTIONAL);
291
+}
292
+
284293 struct Scsi_Host *
285294 NCR_700_detect(struct scsi_host_template *tpnt,
286295 struct NCR_700_Host_Parameters *hostdata, struct device *dev)
....@@ -295,9 +304,13 @@
295304 if(tpnt->sdev_attrs == NULL)
296305 tpnt->sdev_attrs = NCR_700_dev_attrs;
297306
298
- memory = dma_alloc_attrs(dev, TOTAL_MEM_SIZE, &pScript,
299
- GFP_KERNEL, DMA_ATTR_NON_CONSISTENT);
300
- if(memory == NULL) {
307
+ memory = dma_alloc_coherent(dev, TOTAL_MEM_SIZE, &pScript, GFP_KERNEL);
308
+ if (!memory) {
309
+ hostdata->noncoherent = 1;
310
+ memory = dma_alloc_noncoherent(dev, TOTAL_MEM_SIZE, &pScript,
311
+ DMA_BIDIRECTIONAL, GFP_KERNEL);
312
+ }
313
+ if (!memory) {
301314 printk(KERN_ERR "53c700: Failed to allocate memory for driver, detaching\n");
302315 return NULL;
303316 }
....@@ -318,7 +331,6 @@
318331 tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
319332 tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
320333 tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
321
- tpnt->use_clustering = ENABLE_CLUSTERING;
322334 tpnt->slave_configure = NCR_700_slave_configure;
323335 tpnt->slave_destroy = NCR_700_slave_destroy;
324336 tpnt->slave_alloc = NCR_700_slave_alloc;
....@@ -352,11 +364,11 @@
352364 for (j = 0; j < PATCHES; j++)
353365 script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
354366 /* now patch up fixed addresses. */
355
- script_patch_32(hostdata->dev, script, MessageLocation,
367
+ script_patch_32(hostdata, script, MessageLocation,
356368 pScript + MSGOUT_OFFSET);
357
- script_patch_32(hostdata->dev, script, StatusAddress,
369
+ script_patch_32(hostdata, script, StatusAddress,
358370 pScript + STATUS_OFFSET);
359
- script_patch_32(hostdata->dev, script, ReceiveMsgAddress,
371
+ script_patch_32(hostdata, script, ReceiveMsgAddress,
360372 pScript + MSGIN_OFFSET);
361373
362374 hostdata->script = script;
....@@ -408,8 +420,13 @@
408420 struct NCR_700_Host_Parameters *hostdata =
409421 (struct NCR_700_Host_Parameters *)host->hostdata[0];
410422
411
- dma_free_attrs(hostdata->dev, TOTAL_MEM_SIZE, hostdata->script,
412
- hostdata->pScript, DMA_ATTR_NON_CONSISTENT);
423
+ if (hostdata->noncoherent)
424
+ dma_free_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
425
+ hostdata->script, hostdata->pScript,
426
+ DMA_BIDIRECTIONAL);
427
+ else
428
+ dma_free_coherent(hostdata->dev, TOTAL_MEM_SIZE,
429
+ hostdata->script, hostdata->pScript);
413430 return 1;
414431 }
415432
....@@ -817,8 +834,8 @@
817834 shost_printk(KERN_WARNING, host,
818835 "Unexpected SDTR msg\n");
819836 hostdata->msgout[0] = A_REJECT_MSG;
820
- dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
821
- script_patch_16(hostdata->dev, hostdata->script,
837
+ dma_sync_to_dev(hostdata, hostdata->msgout, 1);
838
+ script_patch_16(hostdata, hostdata->script,
822839 MessageCount, 1);
823840 /* SendMsgOut returns, so set up the return
824841 * address */
....@@ -830,9 +847,8 @@
830847 printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
831848 host->host_no, pun, lun);
832849 hostdata->msgout[0] = A_REJECT_MSG;
833
- dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
834
- script_patch_16(hostdata->dev, hostdata->script, MessageCount,
835
- 1);
850
+ dma_sync_to_dev(hostdata, hostdata->msgout, 1);
851
+ script_patch_16(hostdata, hostdata->script, MessageCount, 1);
836852 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
837853
838854 break;
....@@ -845,9 +861,8 @@
845861 printk("\n");
846862 /* just reject it */
847863 hostdata->msgout[0] = A_REJECT_MSG;
848
- dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
849
- script_patch_16(hostdata->dev, hostdata->script, MessageCount,
850
- 1);
864
+ dma_sync_to_dev(hostdata, hostdata->msgout, 1);
865
+ script_patch_16(hostdata, hostdata->script, MessageCount, 1);
851866 /* SendMsgOut returns, so set up the return
852867 * address */
853868 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
....@@ -930,9 +945,8 @@
930945 printk("\n");
931946 /* just reject it */
932947 hostdata->msgout[0] = A_REJECT_MSG;
933
- dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
934
- script_patch_16(hostdata->dev, hostdata->script, MessageCount,
935
- 1);
948
+ dma_sync_to_dev(hostdata, hostdata->msgout, 1);
949
+ script_patch_16(hostdata, hostdata->script, MessageCount, 1);
936950 /* SendMsgOut returns, so set up the return
937951 * address */
938952 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
....@@ -941,7 +955,7 @@
941955 }
942956 NCR_700_writel(temp, host, TEMP_REG);
943957 /* set us up to receive another message */
944
- dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
958
+ dma_sync_from_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
945959 return resume_offset;
946960 }
947961
....@@ -1021,8 +1035,8 @@
10211035 slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
10221036 slot->SG[1].pAddr = 0;
10231037 slot->resume_offset = hostdata->pScript;
1024
- dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
1025
- dma_cache_sync(hostdata->dev, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
1038
+ dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG[0])*2);
1039
+ dma_sync_from_dev(hostdata, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE);
10261040
10271041 /* queue the command for reissue */
10281042 slot->state = NCR_700_SLOT_QUEUED;
....@@ -1142,11 +1156,11 @@
11421156 hostdata->cmd = slot->cmnd;
11431157
11441158 /* re-patch for this command */
1145
- script_patch_32_abs(hostdata->dev, hostdata->script,
1159
+ script_patch_32_abs(hostdata, hostdata->script,
11461160 CommandAddress, slot->pCmd);
1147
- script_patch_16(hostdata->dev, hostdata->script,
1161
+ script_patch_16(hostdata, hostdata->script,
11481162 CommandCount, slot->cmnd->cmd_len);
1149
- script_patch_32_abs(hostdata->dev, hostdata->script,
1163
+ script_patch_32_abs(hostdata, hostdata->script,
11501164 SGScriptStartAddress,
11511165 to32bit(&slot->pSG[0].ins));
11521166
....@@ -1157,14 +1171,14 @@
11571171 * should therefore always clear ACK */
11581172 NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
11591173 host, SXFER_REG);
1160
- dma_cache_sync(hostdata->dev, hostdata->msgin,
1161
- MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
1162
- dma_cache_sync(hostdata->dev, hostdata->msgout,
1163
- MSG_ARRAY_SIZE, DMA_TO_DEVICE);
1174
+ dma_sync_from_dev(hostdata, hostdata->msgin,
1175
+ MSG_ARRAY_SIZE);
1176
+ dma_sync_to_dev(hostdata, hostdata->msgout,
1177
+ MSG_ARRAY_SIZE);
11641178 /* I'm just being paranoid here, the command should
11651179 * already have been flushed from the cache */
1166
- dma_cache_sync(hostdata->dev, slot->cmnd->cmnd,
1167
- slot->cmnd->cmd_len, DMA_TO_DEVICE);
1180
+ dma_sync_to_dev(hostdata, slot->cmnd->cmnd,
1181
+ slot->cmnd->cmd_len);
11681182
11691183
11701184
....@@ -1227,8 +1241,7 @@
12271241 hostdata->reselection_id = reselection_id;
12281242 /* just in case we have a stale simple tag message, clear it */
12291243 hostdata->msgin[1] = 0;
1230
- dma_cache_sync(hostdata->dev, hostdata->msgin,
1231
- MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);
1244
+ dma_sync_to_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
12321245 if(hostdata->tag_negotiated & (1<<reselection_id)) {
12331246 resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
12341247 } else {
....@@ -1342,8 +1355,7 @@
13421355 hostdata->cmd = NULL;
13431356 /* clear any stale simple tag message */
13441357 hostdata->msgin[1] = 0;
1345
- dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
1346
- DMA_BIDIRECTIONAL);
1358
+ dma_sync_to_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
13471359
13481360 if(id == 0xff) {
13491361 /* Selected as target, Ignore */
....@@ -1440,30 +1452,26 @@
14401452 NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
14411453 }
14421454
1443
- script_patch_16(hostdata->dev, hostdata->script, MessageCount, count);
1455
+ script_patch_16(hostdata, hostdata->script, MessageCount, count);
14441456
1457
+ script_patch_ID(hostdata, hostdata->script, Device_ID, 1<<scmd_id(SCp));
14451458
1446
- script_patch_ID(hostdata->dev, hostdata->script,
1447
- Device_ID, 1<<scmd_id(SCp));
1448
-
1449
- script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress,
1459
+ script_patch_32_abs(hostdata, hostdata->script, CommandAddress,
14501460 slot->pCmd);
1451
- script_patch_16(hostdata->dev, hostdata->script, CommandCount,
1452
- SCp->cmd_len);
1461
+ script_patch_16(hostdata, hostdata->script, CommandCount, SCp->cmd_len);
14531462 /* finally plumb the beginning of the SG list into the script
14541463 * */
1455
- script_patch_32_abs(hostdata->dev, hostdata->script,
1464
+ script_patch_32_abs(hostdata, hostdata->script,
14561465 SGScriptStartAddress, to32bit(&slot->pSG[0].ins));
14571466 NCR_700_clear_fifo(SCp->device->host);
14581467
14591468 if(slot->resume_offset == 0)
14601469 slot->resume_offset = hostdata->pScript;
14611470 /* now perform all the writebacks and invalidates */
1462
- dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE);
1463
- dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
1464
- DMA_FROM_DEVICE);
1465
- dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
1466
- dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE);
1471
+ dma_sync_to_dev(hostdata, hostdata->msgout, count);
1472
+ dma_sync_from_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
1473
+ dma_sync_to_dev(hostdata, SCp->cmnd, SCp->cmd_len);
1474
+ dma_sync_from_dev(hostdata, hostdata->status, 1);
14671475
14681476 /* set the synchronous period/offset */
14691477 NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
....@@ -1498,10 +1506,8 @@
14981506 __u8 sstat0 = 0, dstat = 0;
14991507 __u32 dsp;
15001508 struct scsi_cmnd *SCp = hostdata->cmd;
1501
- enum NCR_700_Host_State state;
15021509
15031510 handled = 1;
1504
- state = hostdata->state;
15051511 SCp = hostdata->cmd;
15061512
15071513 if(istat & SCSI_INT_PENDING) {
....@@ -1594,7 +1600,7 @@
15941600 printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
15951601 #endif
15961602 resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
1597
- } else if(dsp >= to32bit(&slot->pSG[0].ins) &&
1603
+ } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) &&
15981604 dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
15991605 int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
16001606 int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
....@@ -1639,7 +1645,7 @@
16391645 slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
16401646 slot->SG[i].pAddr = 0;
16411647 }
1642
- dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
1648
+ dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG));
16431649 /* and pretend we disconnected after
16441650 * the command phase */
16451651 resume_offset = hostdata->pScript + Ent_MsgInDuringData;
....@@ -1752,7 +1758,6 @@
17521758 struct NCR_700_Host_Parameters *hostdata =
17531759 (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
17541760 __u32 move_ins;
1755
- enum dma_data_direction direction;
17561761 struct NCR_700_command_slot *slot;
17571762
17581763 if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
....@@ -1845,7 +1850,7 @@
18451850 case REQUEST_SENSE:
18461851 /* clear the internal sense magic */
18471852 SCp->cmnd[6] = 0;
1848
- /* fall through */
1853
+ fallthrough;
18491854 default:
18501855 /* OK, get it from the command */
18511856 switch(SCp->sc_data_direction) {
....@@ -1869,7 +1874,6 @@
18691874 }
18701875
18711876 /* now build the scatter gather list */
1872
- direction = SCp->sc_data_direction;
18731877 if(move_ins != 0) {
18741878 int i;
18751879 int sg_count;
....@@ -1891,7 +1895,7 @@
18911895 }
18921896 slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
18931897 slot->SG[i].pAddr = 0;
1894
- dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
1898
+ dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG));
18951899 DEBUG((" SETTING %p to %x\n",
18961900 (&slot->pSG[i].ins),
18971901 slot->SG[i].ins));