Lines Matching +full:host +full:- +full:command
1 // SPDX-License-Identifier: GPL-2.0-only
3 * SCSI low-level driver for the 53c94 SCSI bus adaptor found
5 * We assume the 53c94 is connected to a DBDMA (descriptor-based DMA)
50 struct Scsi_Host *host; member
74 if (cmd->sc_data_direction == DMA_TO_DEVICE) { in mac53c94_queue_lck()
76 printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd); in mac53c94_queue_lck()
77 for (i = 0; i < cmd->cmd_len; ++i) in mac53c94_queue_lck()
78 printk(KERN_CONT " %.2x", cmd->cmnd[i]); in mac53c94_queue_lck()
85 cmd->host_scribble = NULL; in mac53c94_queue_lck()
87 state = (struct fsc_state *) cmd->device->host->hostdata; in mac53c94_queue_lck()
89 if (state->request_q == NULL) in mac53c94_queue_lck()
90 state->request_q = cmd; in mac53c94_queue_lck()
92 state->request_qtail->host_scribble = (void *) cmd; in mac53c94_queue_lck()
93 state->request_qtail = cmd; in mac53c94_queue_lck()
95 if (state->phase == idle) in mac53c94_queue_lck()
105 struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata; in DEF_SCSI_QCMD()
106 struct mac53c94_regs __iomem *regs = state->regs; in DEF_SCSI_QCMD()
107 struct dbdma_regs __iomem *dma = state->dma; in DEF_SCSI_QCMD()
110 spin_lock_irqsave(cmd->device->host->host_lock, flags); in DEF_SCSI_QCMD()
112 writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); in DEF_SCSI_QCMD()
113 writeb(CMD_SCSI_RESET, ®s->command); /* assert RST */ in DEF_SCSI_QCMD()
115 writeb(CMD_RESET, ®s->command); in DEF_SCSI_QCMD()
118 writeb(CMD_NOP, ®s->command); in DEF_SCSI_QCMD()
120 spin_unlock_irqrestore(cmd->device->host->host_lock, flags); in DEF_SCSI_QCMD()
126 struct mac53c94_regs __iomem *regs = state->regs; in mac53c94_init()
127 struct dbdma_regs __iomem *dma = state->dma; in mac53c94_init()
129 writeb(state->host->this_id | CF1_PAR_ENABLE, ®s->config1); in mac53c94_init()
130 writeb(TIMO_VAL(250), ®s->sel_timeout); /* 250ms */ in mac53c94_init()
131 writeb(CLKF_VAL(state->clk_freq), ®s->clk_factor); in mac53c94_init()
132 writeb(CF2_FEATURE_EN, ®s->config2); in mac53c94_init()
133 writeb(0, ®s->config3); in mac53c94_init()
134 writeb(0, ®s->sync_period); in mac53c94_init()
135 writeb(0, ®s->sync_offset); in mac53c94_init()
136 (void)readb(®s->interrupt); in mac53c94_init()
137 writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); in mac53c94_init()
141 * Start the next command for a 53C94.
147 struct mac53c94_regs __iomem *regs = state->regs; in mac53c94_start()
150 if (state->phase != idle || state->current_req != NULL) in mac53c94_start()
152 if (state->request_q == NULL) in mac53c94_start()
154 state->current_req = cmd = state->request_q; in mac53c94_start()
155 state->request_q = (struct scsi_cmnd *) cmd->host_scribble; in mac53c94_start()
158 writeb(0, ®s->count_lo); in mac53c94_start()
159 writeb(0, ®s->count_mid); in mac53c94_start()
160 writeb(0, ®s->count_hi); in mac53c94_start()
161 writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); in mac53c94_start()
163 writeb(CMD_FLUSH, ®s->command); in mac53c94_start()
165 writeb(cmd->device->id, ®s->dest_id); in mac53c94_start()
166 writeb(0, ®s->sync_period); in mac53c94_start()
167 writeb(0, ®s->sync_offset); in mac53c94_start()
169 /* load the command into the FIFO */ in mac53c94_start()
170 for (i = 0; i < cmd->cmd_len; ++i) in mac53c94_start()
171 writeb(cmd->cmnd[i], ®s->fifo); in mac53c94_start()
174 writeb(CMD_SELECT, ®s->command); in mac53c94_start()
175 state->phase = selecting; in mac53c94_start()
183 struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host; in do_mac53c94_interrupt()
185 spin_lock_irqsave(dev->host_lock, flags); in do_mac53c94_interrupt()
187 spin_unlock_irqrestore(dev->host_lock, flags); in do_mac53c94_interrupt()
194 struct mac53c94_regs __iomem *regs = state->regs; in mac53c94_interrupt()
195 struct dbdma_regs __iomem *dma = state->dma; in mac53c94_interrupt()
196 struct scsi_cmnd *const cmd = state->current_req; in mac53c94_interrupt()
205 seq = readb(®s->seqstep); in mac53c94_interrupt()
206 stat = readb(®s->status); in mac53c94_interrupt()
207 intr = readb(®s->interrupt); in mac53c94_interrupt()
211 intr, stat, seq, state->phase); in mac53c94_interrupt()
217 writeb(CMD_NOP, ®s->command); in mac53c94_interrupt()
218 writel(RUN << 16, &dma->control); /* stop dma */ in mac53c94_interrupt()
224 intr, stat, seq, state->phase); in mac53c94_interrupt()
232 intr, stat, seq, state->phase); in mac53c94_interrupt()
235 writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); in mac53c94_interrupt()
238 printk(KERN_DEBUG "53c94: interrupt with no command active?\n"); in mac53c94_interrupt()
246 switch (state->phase) { in mac53c94_interrupt()
259 printk(KERN_DEBUG "seq step %x after command\n", seq); in mac53c94_interrupt()
263 writeb(CMD_NOP, ®s->command); in mac53c94_interrupt()
267 nb = mcmd->this_residual; in mac53c94_interrupt()
270 mcmd->this_residual -= nb; in mac53c94_interrupt()
271 writeb(nb, ®s->count_lo); in mac53c94_interrupt()
272 writeb(nb >> 8, ®s->count_mid); in mac53c94_interrupt()
273 writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); in mac53c94_interrupt()
274 writel(virt_to_phys(state->dma_cmds), &dma->cmdptr); in mac53c94_interrupt()
275 writel((RUN << 16) | RUN, &dma->control); in mac53c94_interrupt()
276 writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); in mac53c94_interrupt()
277 state->phase = dataing; in mac53c94_interrupt()
281 writeb(CMD_I_COMPLETE, ®s->command); in mac53c94_interrupt()
282 state->phase = completing; in mac53c94_interrupt()
297 if (mcmd->this_residual != 0 in mac53c94_interrupt()
300 nb = mcmd->this_residual; in mac53c94_interrupt()
303 mcmd->this_residual -= nb; in mac53c94_interrupt()
304 writeb(nb, ®s->count_lo); in mac53c94_interrupt()
305 writeb(nb >> 8, ®s->count_mid); in mac53c94_interrupt()
306 writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); in mac53c94_interrupt()
307 writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); in mac53c94_interrupt()
313 writel(RUN << 16, &dma->control); /* stop dma */ in mac53c94_interrupt()
316 writeb(CMD_I_COMPLETE, ®s->command); in mac53c94_interrupt()
317 state->phase = completing; in mac53c94_interrupt()
325 mcmd->status = readb(®s->fifo); in mac53c94_interrupt()
326 mcmd->message = readb(®s->fifo); in mac53c94_interrupt()
327 writeb(CMD_ACCEPT_MSG, ®s->command); in mac53c94_interrupt()
328 state->phase = busfreeing; in mac53c94_interrupt()
334 cmd_done(state, (DID_OK << 16) + (mcmd->message << 8) + mcmd->status); in mac53c94_interrupt()
337 printk(KERN_DEBUG "don't know about phase %d\n", state->phase); in mac53c94_interrupt()
345 cmd = state->current_req; in cmd_done()
347 cmd->result = result; in cmd_done()
349 state->current_req = NULL; in cmd_done()
351 state->phase = idle; in cmd_done()
371 dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ? in set_dma_cmds()
373 dcmds = state->dma_cmds; in set_dma_cmds()
382 dcmds->req_count = cpu_to_le16(dma_len); in set_dma_cmds()
383 dcmds->command = cpu_to_le16(dma_cmd); in set_dma_cmds()
384 dcmds->phy_addr = cpu_to_le32(dma_addr); in set_dma_cmds()
385 dcmds->xfer_status = 0; in set_dma_cmds()
389 dma_cmd += OUTPUT_LAST - OUTPUT_MORE; in set_dma_cmds()
390 dcmds[-1].command = cpu_to_le16(dma_cmd); in set_dma_cmds()
391 dcmds->command = cpu_to_le16(DBDMA_STOP); in set_dma_cmds()
392 mac53c94_priv(cmd)->this_residual = total; in set_dma_cmds()
412 struct Scsi_Host *host; in mac53c94_probe() local
415 int proplen, rc = -ENODEV; in mac53c94_probe()
421 return -ENODEV; in mac53c94_probe()
426 return -EBUSY; in mac53c94_probe()
429 host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); in mac53c94_probe()
430 if (host == NULL) { in mac53c94_probe()
431 printk(KERN_ERR "mac53c94: couldn't register host"); in mac53c94_probe()
432 rc = -ENOMEM; in mac53c94_probe()
436 state = (struct fsc_state *) host->hostdata; in mac53c94_probe()
438 state->host = host; in mac53c94_probe()
439 state->pdev = pdev; in mac53c94_probe()
440 state->mdev = mdev; in mac53c94_probe()
442 state->regs = (struct mac53c94_regs __iomem *) in mac53c94_probe()
444 state->intr = macio_irq(mdev, 0); in mac53c94_probe()
445 state->dma = (struct dbdma_regs __iomem *) in mac53c94_probe()
447 state->dmaintr = macio_irq(mdev, 1); in mac53c94_probe()
448 if (state->regs == NULL || state->dma == NULL) { in mac53c94_probe()
453 clkprop = of_get_property(node, "clock-frequency", &proplen); in mac53c94_probe()
457 state->clk_freq = 25000000; in mac53c94_probe()
459 state->clk_freq = *(int *)clkprop; in mac53c94_probe()
461 /* Space for dma command list: +1 for stop command, in mac53c94_probe()
465 dma_cmd_space = kmalloc_array(host->sg_tablesize + 2, in mac53c94_probe()
470 "command space for %pOF\n", node); in mac53c94_probe()
471 rc = -ENOMEM; in mac53c94_probe()
475 state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); in mac53c94_probe()
476 memset(state->dma_cmds, 0, (host->sg_tablesize + 1) in mac53c94_probe()
478 state->dma_cmd_space = dma_cmd_space; in mac53c94_probe()
482 if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94",state)) { in mac53c94_probe()
484 state->intr, node); in mac53c94_probe()
488 rc = scsi_add_host(host, &mdev->ofdev.dev); in mac53c94_probe()
492 scsi_scan_host(host); in mac53c94_probe()
496 free_irq(state->intr, state); in mac53c94_probe()
498 kfree(state->dma_cmd_space); in mac53c94_probe()
500 if (state->dma != NULL) in mac53c94_probe()
501 iounmap(state->dma); in mac53c94_probe()
502 if (state->regs != NULL) in mac53c94_probe()
503 iounmap(state->regs); in mac53c94_probe()
504 scsi_host_put(host); in mac53c94_probe()
514 struct Scsi_Host *host = fp->host; in mac53c94_remove() local
516 scsi_remove_host(host); in mac53c94_remove()
518 free_irq(fp->intr, fp); in mac53c94_remove()
520 if (fp->regs) in mac53c94_remove()
521 iounmap(fp->regs); in mac53c94_remove()
522 if (fp->dma) in mac53c94_remove()
523 iounmap(fp->dma); in mac53c94_remove()
524 kfree(fp->dma_cmd_space); in mac53c94_remove()
526 scsi_host_put(host); in mac53c94_remove()