a3000.c (53555fb7bceb14f5fdb9358290daf64d0ea0f56a) | a3000.c (dbb2da557a6a87c88bbb4b1fef037091b57f701b) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2#include <linux/types.h> 3#include <linux/mm.h> 4#include <linux/ioport.h> 5#include <linux/init.h> 6#include <linux/slab.h> 7#include <linux/spinlock.h> 8#include <linux/interrupt.h> --- 34 unchanged lines hidden (view full) --- 43 return IRQ_HANDLED; 44 } 45 pr_warn("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); 46 return IRQ_NONE; 47} 48 49static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 50{ | 1// SPDX-License-Identifier: GPL-2.0-only 2#include <linux/types.h> 3#include <linux/mm.h> 4#include <linux/ioport.h> 5#include <linux/init.h> 6#include <linux/slab.h> 7#include <linux/spinlock.h> 8#include <linux/interrupt.h> --- 34 unchanged lines hidden (view full) --- 43 return IRQ_HANDLED; 44 } 45 pr_warn("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); 46 return IRQ_NONE; 47} 48 49static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 50{ |
51 struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd); |
|
51 struct Scsi_Host *instance = cmd->device->host; 52 struct a3000_hostdata *hdata = shost_priv(instance); 53 struct WD33C93_hostdata *wh = &hdata->wh; 54 struct a3000_scsiregs *regs = hdata->regs; 55 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; | 52 struct Scsi_Host *instance = cmd->device->host; 53 struct a3000_hostdata *hdata = shost_priv(instance); 54 struct WD33C93_hostdata *wh = &hdata->wh; 55 struct a3000_scsiregs *regs = hdata->regs; 56 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; |
56 unsigned long addr = virt_to_bus(cmd->SCp.ptr); | 57 unsigned long addr = virt_to_bus(scsi_pointer->ptr); |
57 58 /* 59 * if the physical address has the wrong alignment, or if 60 * physical address is bad, or if it is a write and at the 61 * end of a physical memory chunk, then allocate a bounce 62 * buffer 63 */ 64 if (addr & A3000_XFER_MASK) { | 58 59 /* 60 * if the physical address has the wrong alignment, or if 61 * physical address is bad, or if it is a write and at the 62 * end of a physical memory chunk, then allocate a bounce 63 * buffer 64 */ 65 if (addr & A3000_XFER_MASK) { |
65 wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; | 66 wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff; |
66 wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, 67 GFP_KERNEL); 68 69 /* can't allocate memory; use PIO */ 70 if (!wh->dma_bounce_buffer) { 71 wh->dma_bounce_len = 0; 72 return 1; 73 } 74 75 if (!dir_in) { 76 /* copy to bounce buffer for a write */ | 67 wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, 68 GFP_KERNEL); 69 70 /* can't allocate memory; use PIO */ 71 if (!wh->dma_bounce_buffer) { 72 wh->dma_bounce_len = 0; 73 return 1; 74 } 75 76 if (!dir_in) { 77 /* copy to bounce buffer for a write */ |
77 memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, 78 cmd->SCp.this_residual); | 78 memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr, 79 scsi_pointer->this_residual); |
79 } 80 81 addr = virt_to_bus(wh->dma_bounce_buffer); 82 } 83 84 /* setup dma direction */ 85 if (!dir_in) 86 cntr |= CNTR_DDIR; 87 88 /* remember direction */ 89 wh->dma_dir = dir_in; 90 91 regs->CNTR = cntr; 92 93 /* setup DMA *physical* address */ 94 regs->ACR = addr; 95 96 if (dir_in) { 97 /* invalidate any cache */ | 80 } 81 82 addr = virt_to_bus(wh->dma_bounce_buffer); 83 } 84 85 /* setup dma direction */ 86 if (!dir_in) 87 cntr |= CNTR_DDIR; 88 89 /* remember direction */ 90 wh->dma_dir = dir_in; 91 92 regs->CNTR = cntr; 93 94 /* setup DMA *physical* address */ 95 regs->ACR = addr; 96 97 if (dir_in) { 98 /* invalidate any cache */ |
98 cache_clear(addr, cmd->SCp.this_residual); | 99 cache_clear(addr, scsi_pointer->this_residual); |
99 } else { 100 /* push any dirty cache */ | 100 } else { 101 /* push any dirty cache */ |
101 cache_push(addr, cmd->SCp.this_residual); | 102 cache_push(addr, scsi_pointer->this_residual); |
102 } 103 104 /* start DMA */ 105 mb(); /* make sure setup is completed */ 106 regs->ST_DMA = 1; 107 mb(); /* make sure DMA has started before next IO */ 108 109 /* return success */ 110 return 0; 111} 112 113static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 114 int status) 115{ | 103 } 104 105 /* start DMA */ 106 mb(); /* make sure setup is completed */ 107 regs->ST_DMA = 1; 108 mb(); /* make sure DMA has started before next IO */ 109 110 /* return success */ 111 return 0; 112} 113 114static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 115 int status) 116{ |
117 struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(SCpnt); |
|
116 struct a3000_hostdata *hdata = shost_priv(instance); 117 struct WD33C93_hostdata *wh = &hdata->wh; 118 struct a3000_scsiregs *regs = hdata->regs; 119 120 /* disable SCSI interrupts */ 121 unsigned short cntr = CNTR_PDMD; 122 123 if (!wh->dma_dir) --- 24 unchanged lines hidden (view full) --- 148 /* restore the CONTROL bits (minus the direction flag) */ 149 regs->CNTR = CNTR_PDMD | CNTR_INTEN; 150 mb(); /* make sure CNTR is updated before next IO */ 151 152 /* copy from a bounce buffer, if necessary */ 153 if (status && wh->dma_bounce_buffer) { 154 if (SCpnt) { 155 if (wh->dma_dir && SCpnt) | 118 struct a3000_hostdata *hdata = shost_priv(instance); 119 struct WD33C93_hostdata *wh = &hdata->wh; 120 struct a3000_scsiregs *regs = hdata->regs; 121 122 /* disable SCSI interrupts */ 123 unsigned short cntr = CNTR_PDMD; 124 125 if (!wh->dma_dir) --- 24 unchanged lines hidden (view full) --- 150 /* restore the CONTROL bits (minus the direction flag) */ 151 regs->CNTR = CNTR_PDMD | CNTR_INTEN; 152 mb(); /* make sure CNTR is updated before next IO */ 153 154 /* copy from a bounce buffer, if necessary */ 155 if (status && wh->dma_bounce_buffer) { 156 if (SCpnt) { 157 if (wh->dma_dir && SCpnt) |
156 memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, 157 SCpnt->SCp.this_residual); | 158 memcpy(scsi_pointer->ptr, wh->dma_bounce_buffer, 159 scsi_pointer->this_residual); |
158 kfree(wh->dma_bounce_buffer); 159 wh->dma_bounce_buffer = NULL; 160 wh->dma_bounce_len = 0; 161 } else { 162 kfree(wh->dma_bounce_buffer); 163 wh->dma_bounce_buffer = NULL; 164 wh->dma_bounce_len = 0; 165 } --- 8 unchanged lines hidden (view full) --- 174 .proc_name = "A3000", 175 .queuecommand = wd33c93_queuecommand, 176 .eh_abort_handler = wd33c93_abort, 177 .eh_host_reset_handler = wd33c93_host_reset, 178 .can_queue = CAN_QUEUE, 179 .this_id = 7, 180 .sg_tablesize = SG_ALL, 181 .cmd_per_lun = CMD_PER_LUN, | 160 kfree(wh->dma_bounce_buffer); 161 wh->dma_bounce_buffer = NULL; 162 wh->dma_bounce_len = 0; 163 } else { 164 kfree(wh->dma_bounce_buffer); 165 wh->dma_bounce_buffer = NULL; 166 wh->dma_bounce_len = 0; 167 } --- 8 unchanged lines hidden (view full) --- 176 .proc_name = "A3000", 177 .queuecommand = wd33c93_queuecommand, 178 .eh_abort_handler = wd33c93_abort, 179 .eh_host_reset_handler = wd33c93_host_reset, 180 .can_queue = CAN_QUEUE, 181 .this_id = 7, 182 .sg_tablesize = SG_ALL, 183 .cmd_per_lun = CMD_PER_LUN, |
184 .cmd_size = sizeof(struct scsi_pointer), |
|
182}; 183 184static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) 185{ 186 struct resource *res; 187 struct Scsi_Host *instance; 188 int error; 189 struct a3000_scsiregs *regs; --- 83 unchanged lines hidden --- | 185}; 186 187static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) 188{ 189 struct resource *res; 190 struct Scsi_Host *instance; 191 int error; 192 struct a3000_scsiregs *regs; --- 83 unchanged lines hidden --- |