io_uring: inline io_fail_links()
[linux-2.6-microblaze.git] / drivers / scsi / 53c700.c
index 84b57a8..5117d90 100644 (file)
@@ -269,6 +269,27 @@ NCR_700_get_SXFER(struct scsi_device *SDp)
                                              spi_period(SDp->sdev_target));
 }
 
+static inline dma_addr_t virt_to_dma(struct NCR_700_Host_Parameters *h, void *p)
+{
+       return h->pScript + ((uintptr_t)p - (uintptr_t)h->script);
+}
+
+static inline void dma_sync_to_dev(struct NCR_700_Host_Parameters *h,
+               void *addr, size_t size)
+{
+       if (h->noncoherent)
+               dma_sync_single_for_device(h->dev, virt_to_dma(h, addr),
+                                          size, DMA_BIDIRECTIONAL);
+}
+
+static inline void dma_sync_from_dev(struct NCR_700_Host_Parameters *h,
+               void *addr, size_t size)
+{
+       if (h->noncoherent)
+               dma_sync_single_for_device(h->dev, virt_to_dma(h, addr), size,
+                                          DMA_BIDIRECTIONAL);
+}
+
 struct Scsi_Host *
 NCR_700_detect(struct scsi_host_template *tpnt,
               struct NCR_700_Host_Parameters *hostdata, struct device *dev)
@@ -283,9 +304,13 @@ NCR_700_detect(struct scsi_host_template *tpnt,
        if(tpnt->sdev_attrs == NULL)
                tpnt->sdev_attrs = NCR_700_dev_attrs;
 
-       memory = dma_alloc_attrs(dev, TOTAL_MEM_SIZE, &pScript,
-                                GFP_KERNEL, DMA_ATTR_NON_CONSISTENT);
-       if(memory == NULL) {
+       memory = dma_alloc_coherent(dev, TOTAL_MEM_SIZE, &pScript, GFP_KERNEL);
+       if (!memory) {
+               hostdata->noncoherent = 1;
+               memory = dma_alloc_noncoherent(dev, TOTAL_MEM_SIZE, &pScript,
+                                        DMA_BIDIRECTIONAL, GFP_KERNEL);
+       }
+       if (!memory) {
                printk(KERN_ERR "53c700: Failed to allocate memory for driver, detaching\n");
                return NULL;
        }
@@ -339,11 +364,11 @@ NCR_700_detect(struct scsi_host_template *tpnt,
        for (j = 0; j < PATCHES; j++)
                script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
        /* now patch up fixed addresses. */
-       script_patch_32(hostdata->dev, script, MessageLocation,
+       script_patch_32(hostdata, script, MessageLocation,
                        pScript + MSGOUT_OFFSET);
-       script_patch_32(hostdata->dev, script, StatusAddress,
+       script_patch_32(hostdata, script, StatusAddress,
                        pScript + STATUS_OFFSET);
-       script_patch_32(hostdata->dev, script, ReceiveMsgAddress,
+       script_patch_32(hostdata, script, ReceiveMsgAddress,
                        pScript + MSGIN_OFFSET);
 
        hostdata->script = script;
@@ -395,8 +420,13 @@ NCR_700_release(struct Scsi_Host *host)
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-       dma_free_attrs(hostdata->dev, TOTAL_MEM_SIZE, hostdata->script,
-                      hostdata->pScript, DMA_ATTR_NON_CONSISTENT);
+       if (hostdata->noncoherent)
+               dma_free_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
+                               hostdata->script, hostdata->pScript,
+                               DMA_BIDIRECTIONAL);
+       else
+               dma_free_coherent(hostdata->dev, TOTAL_MEM_SIZE,
+                                 hostdata->script, hostdata->pScript);
        return 1;
 }
 
@@ -804,8 +834,8 @@ process_extended_message(struct Scsi_Host *host,
                        shost_printk(KERN_WARNING, host,
                                "Unexpected SDTR msg\n");
                        hostdata->msgout[0] = A_REJECT_MSG;
-                       dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
-                       script_patch_16(hostdata->dev, hostdata->script,
+                       dma_sync_to_dev(hostdata, hostdata->msgout, 1);
+                       script_patch_16(hostdata, hostdata->script,
                                        MessageCount, 1);
                        /* SendMsgOut returns, so set up the return
                         * address */
@@ -817,9 +847,8 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
                       host->host_no, pun, lun);
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
-                               1);
+               dma_sync_to_dev(hostdata, hostdata->msgout, 1);
+               script_patch_16(hostdata, hostdata->script, MessageCount, 1);
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
 
                break;
@@ -832,9 +861,8 @@ process_extended_message(struct Scsi_Host *host,
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
-                               1);
+               dma_sync_to_dev(hostdata, hostdata->msgout, 1);
+               script_patch_16(hostdata, hostdata->script, MessageCount, 1);
                /* SendMsgOut returns, so set up the return
                 * address */
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -917,9 +945,8 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
-                               1);
+               dma_sync_to_dev(hostdata, hostdata->msgout, 1);
+               script_patch_16(hostdata, hostdata->script, MessageCount, 1);
                /* SendMsgOut returns, so set up the return
                 * address */
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -928,7 +955,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
        }
        NCR_700_writel(temp, host, TEMP_REG);
        /* set us up to receive another message */
-       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
+       dma_sync_from_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
        return resume_offset;
 }
 
@@ -1008,8 +1035,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                                slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
                                slot->SG[1].pAddr = 0;
                                slot->resume_offset = hostdata->pScript;
-                               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
-                               dma_cache_sync(hostdata->dev, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
+                               dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG[0])*2);
+                               dma_sync_from_dev(hostdata, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE);
 
                                /* queue the command for reissue */
                                slot->state = NCR_700_SLOT_QUEUED;
@@ -1129,11 +1156,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                        hostdata->cmd = slot->cmnd;
 
                        /* re-patch for this command */
-                       script_patch_32_abs(hostdata->dev, hostdata->script,
+                       script_patch_32_abs(hostdata, hostdata->script,
                                            CommandAddress, slot->pCmd);
-                       script_patch_16(hostdata->dev, hostdata->script,
+                       script_patch_16(hostdata, hostdata->script,
                                        CommandCount, slot->cmnd->cmd_len);
-                       script_patch_32_abs(hostdata->dev, hostdata->script,
+                       script_patch_32_abs(hostdata, hostdata->script,
                                            SGScriptStartAddress,
                                            to32bit(&slot->pSG[0].ins));
 
@@ -1144,14 +1171,14 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                         * should therefore always clear ACK */
                        NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
                                       host, SXFER_REG);
-                       dma_cache_sync(hostdata->dev, hostdata->msgin,
-                                      MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
-                       dma_cache_sync(hostdata->dev, hostdata->msgout,
-                                      MSG_ARRAY_SIZE, DMA_TO_DEVICE);
+                       dma_sync_from_dev(hostdata, hostdata->msgin,
+                                      MSG_ARRAY_SIZE);
+                       dma_sync_to_dev(hostdata, hostdata->msgout,
+                                      MSG_ARRAY_SIZE);
                        /* I'm just being paranoid here, the command should
                         * already have been flushed from the cache */
-                       dma_cache_sync(hostdata->dev, slot->cmnd->cmnd,
-                                      slot->cmnd->cmd_len, DMA_TO_DEVICE);
+                       dma_sync_to_dev(hostdata, slot->cmnd->cmnd,
+                                      slot->cmnd->cmd_len);
 
 
                        
@@ -1214,8 +1241,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                hostdata->reselection_id = reselection_id;
                /* just in case we have a stale simple tag message, clear it */
                hostdata->msgin[1] = 0;
-               dma_cache_sync(hostdata->dev, hostdata->msgin,
-                              MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);
+               dma_sync_to_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
                if(hostdata->tag_negotiated & (1<<reselection_id)) {
                        resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
                } else {
@@ -1329,8 +1355,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
        hostdata->cmd = NULL;
        /* clear any stale simple tag message */
        hostdata->msgin[1] = 0;
-       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
-                      DMA_BIDIRECTIONAL);
+       dma_sync_to_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
 
        if(id == 0xff) {
                /* Selected as target, Ignore */
@@ -1427,30 +1452,26 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
                NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
        }
 
-       script_patch_16(hostdata->dev, hostdata->script, MessageCount, count);
-
+       script_patch_16(hostdata, hostdata->script, MessageCount, count);
 
-       script_patch_ID(hostdata->dev, hostdata->script,
-                       Device_ID, 1<<scmd_id(SCp));
+       script_patch_ID(hostdata, hostdata->script, Device_ID, 1<<scmd_id(SCp));
 
-       script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress,
+       script_patch_32_abs(hostdata, hostdata->script, CommandAddress,
                            slot->pCmd);
-       script_patch_16(hostdata->dev, hostdata->script, CommandCount,
-                       SCp->cmd_len);
+       script_patch_16(hostdata, hostdata->script, CommandCount, SCp->cmd_len);
        /* finally plumb the beginning of the SG list into the script
         * */
-       script_patch_32_abs(hostdata->dev, hostdata->script,
+       script_patch_32_abs(hostdata, hostdata->script,
                            SGScriptStartAddress, to32bit(&slot->pSG[0].ins));
        NCR_700_clear_fifo(SCp->device->host);
 
        if(slot->resume_offset == 0)
                slot->resume_offset = hostdata->pScript;
        /* now perform all the writebacks and invalidates */
-       dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE);
-       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
-                      DMA_FROM_DEVICE);
-       dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
-       dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE);
+       dma_sync_to_dev(hostdata, hostdata->msgout, count);
+       dma_sync_from_dev(hostdata, hostdata->msgin, MSG_ARRAY_SIZE);
+       dma_sync_to_dev(hostdata, SCp->cmnd, SCp->cmd_len);
+       dma_sync_from_dev(hostdata, hostdata->status, 1);
 
        /* set the synchronous period/offset */
        NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1626,7 +1647,7 @@ NCR_700_intr(int irq, void *dev_id)
                                        slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
                                        slot->SG[i].pAddr = 0;
                                }
-                               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+                               dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG));
                                /* and pretend we disconnected after
                                 * the command phase */
                                resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1878,7 +1899,7 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)
                }
                slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
                slot->SG[i].pAddr = 0;
-               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+               dma_sync_to_dev(hostdata, slot->SG, sizeof(slot->SG));
                DEBUG((" SETTING %p to %x\n",
                       (&slot->pSG[i].ins),
                       slot->SG[i].ins));