Lines Matching full:host

176 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
178 static int acornscsi_reconnect_finish(AS_Host *host);
179 static void acornscsi_dma_cleanup(AS_Host *host);
180 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
195 static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value) in sbic_arm_write() argument
197 writeb(reg, host->base + SBIC_REGIDX); in sbic_arm_write()
198 writeb(value, host->base + SBIC_REGVAL); in sbic_arm_write()
201 static inline int sbic_arm_read(AS_Host *host, unsigned int reg) in sbic_arm_read() argument
204 return readl(host->base + SBIC_REGIDX) & 255; in sbic_arm_read()
205 writeb(reg, host->base + SBIC_REGIDX); in sbic_arm_read()
206 return readl(host->base + SBIC_REGVAL) & 255; in sbic_arm_read()
209 #define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL) argument
210 #define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL) argument
213 #define dmac_read(host,reg) \ argument
214 readb((host)->base + DMAC_OFFSET + ((reg) << 2))
216 #define dmac_write(host,reg,value) \ argument
217 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
219 #define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG) argument
221 static inline unsigned int dmac_address(AS_Host *host) in dmac_address() argument
223 return dmac_read(host, DMAC_TXADRHI) << 16 | in dmac_address()
224 dmac_read(host, DMAC_TXADRMD) << 8 | in dmac_address()
225 dmac_read(host, DMAC_TXADRLO); in dmac_address()
229 void acornscsi_dumpdma(AS_Host *host, char *where) in acornscsi_dumpdma() argument
233 mode = dmac_read(host, DMAC_MODECON); in acornscsi_dumpdma()
234 addr = dmac_address(host); in acornscsi_dumpdma()
235 len = dmac_read(host, DMAC_TXCNTHI) << 8 | in acornscsi_dumpdma()
236 dmac_read(host, DMAC_TXCNTLO); in acornscsi_dumpdma()
239 host->host->host_no, where, in acornscsi_dumpdma()
241 dmac_read(host, DMAC_MASKREG)); in acornscsi_dumpdma()
243 printk("DMA @%06x, ", host->dma.start_addr); in acornscsi_dumpdma()
244 printk("BH @%p +%04x, ", host->scsi.SCp.ptr, in acornscsi_dumpdma()
245 host->scsi.SCp.this_residual); in acornscsi_dumpdma()
246 printk("DT @+%04x ST @+%04x", host->dma.transferred, in acornscsi_dumpdma()
247 host->scsi.SCp.scsi_xferred); in acornscsi_dumpdma()
253 unsigned long acornscsi_sbic_xfcount(AS_Host *host) in acornscsi_sbic_xfcount() argument
257 length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16; in acornscsi_sbic_xfcount()
258 length |= sbic_arm_readnext(host) << 8; in acornscsi_sbic_xfcount()
259 length |= sbic_arm_readnext(host); in acornscsi_sbic_xfcount()
265 acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg) in acornscsi_sbic_wait() argument
270 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_sbic_wait()
278 printk("scsi%d: timeout while %s\n", host->host->host_no, msg); in acornscsi_sbic_wait()
284 int acornscsi_sbic_issuecmd(AS_Host *host, int command) in acornscsi_sbic_issuecmd() argument
286 if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command")) in acornscsi_sbic_issuecmd()
289 sbic_arm_write(host, SBIC_CMND, command); in acornscsi_sbic_issuecmd()
310 void acornscsi_resetcard(AS_Host *host) in acornscsi_resetcard() argument
315 host->card.page_reg = 0x80; in acornscsi_resetcard()
316 writeb(host->card.page_reg, host->fast + PAGE_REG); in acornscsi_resetcard()
321 host->card.page_reg = 0; in acornscsi_resetcard()
322 writeb(host->card.page_reg, host->fast + PAGE_REG); in acornscsi_resetcard()
329 if (readb(host->fast + INT_REG) & 8) in acornscsi_resetcard()
336 host->host->host_no); in acornscsi_resetcard()
338 sbic_arm_read(host, SBIC_ASR); in acornscsi_resetcard()
339 sbic_arm_read(host, SBIC_SSR); in acornscsi_resetcard()
342 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); in acornscsi_resetcard()
343 sbic_arm_write(host, SBIC_CMND, CMND_RESET); in acornscsi_resetcard()
350 if (readb(host->fast + INT_REG) & 8) in acornscsi_resetcard()
357 host->host->host_no); in acornscsi_resetcard()
359 sbic_arm_read(host, SBIC_ASR); in acornscsi_resetcard()
360 if (sbic_arm_read(host, SBIC_SSR) != 0x01) in acornscsi_resetcard()
362 host->host->host_no); in acornscsi_resetcard()
364 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); in acornscsi_resetcard()
365 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); in acornscsi_resetcard()
366 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); in acornscsi_resetcard()
367 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); in acornscsi_resetcard()
369 host->card.page_reg = 0x40; in acornscsi_resetcard()
370 writeb(host->card.page_reg, host->fast + PAGE_REG); in acornscsi_resetcard()
373 dmac_write(host, DMAC_INIT, 0); in acornscsi_resetcard()
375 dmac_write(host, DMAC_INIT, INIT_8BIT); in acornscsi_resetcard()
376 dmac_write(host, DMAC_CHANNEL, CHANNEL_0); in acornscsi_resetcard()
377 dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0); in acornscsi_resetcard()
378 dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1); in acornscsi_resetcard()
381 host->SCpnt = NULL; in acornscsi_resetcard()
382 host->scsi.phase = PHASE_IDLE; in acornscsi_resetcard()
383 host->scsi.disconnectable = 0; in acornscsi_resetcard()
385 memset(host->busyluns, 0, sizeof(host->busyluns)); in acornscsi_resetcard()
388 host->device[i].sync_state = SYNC_NEGOCIATE; in acornscsi_resetcard()
389 host->device[i].disconnect_ok = 1; in acornscsi_resetcard()
495 acornscsi_dumplogline(AS_Host *host, int target, int line) in acornscsi_dumplogline() argument
500 ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT; in acornscsi_dumplogline()
507 prev = host->status[target][ptr].when; in acornscsi_dumplogline()
509 for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) { in acornscsi_dumplogline()
512 if (!host->status[target][ptr].when) in acornscsi_dumplogline()
517 printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ', in acornscsi_dumplogline()
518 host->status[target][ptr].ph); in acornscsi_dumplogline()
522 printk(" %02X", host->status[target][ptr].ssr); in acornscsi_dumplogline()
526 time_diff = host->status[target][ptr].when - prev; in acornscsi_dumplogline()
527 prev = host->status[target][ptr].when; in acornscsi_dumplogline()
542 void acornscsi_dumplog(AS_Host *host, int target) in acornscsi_dumplog() argument
545 acornscsi_dumplogline(host, target, 0); in acornscsi_dumplog()
546 acornscsi_dumplogline(host, target, 1); in acornscsi_dumplog()
547 acornscsi_dumplogline(host, target, 2); in acornscsi_dumplog()
557 char acornscsi_target(AS_Host *host) in acornscsi_target() argument
559 if (host->SCpnt) in acornscsi_target()
560 return '0' + host->SCpnt->device->id; in acornscsi_target()
688 * Function: acornscsi_kick(AS_Host *host)
690 * Params : host - host to send command to
695 intr_ret_t acornscsi_kick(AS_Host *host) in acornscsi_kick() argument
701 SCpnt = host->origSCpnt; in acornscsi_kick()
702 host->origSCpnt = NULL; in acornscsi_kick()
706 SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns); in acornscsi_kick()
713 if (host->scsi.disconnectable && host->SCpnt) { in acornscsi_kick()
714 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); in acornscsi_kick()
715 host->scsi.disconnectable = 0; in acornscsi_kick()
717 DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n", in acornscsi_kick()
718 host->host->host_no, acornscsi_target(host))); in acornscsi_kick()
720 host->SCpnt = NULL; in acornscsi_kick()
727 if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) { in acornscsi_kick()
728 sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id); in acornscsi_kick()
729 sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN); in acornscsi_kick()
733 * claim host busy - all of these must happen atomically wrt in acornscsi_kick()
736 host->scsi.phase = PHASE_CONNECTING; in acornscsi_kick()
737 host->SCpnt = SCpnt; in acornscsi_kick()
738 host->scsi.SCp = SCpnt->SCp; in acornscsi_kick()
739 host->dma.xfer_setup = 0; in acornscsi_kick()
740 host->dma.xfer_required = 0; in acornscsi_kick()
741 host->dma.xfer_done = 0; in acornscsi_kick()
745 host->host->host_no, '0' + SCpnt->device->id, in acornscsi_kick()
762 (u8)(SCpnt->device->lun & 0x07), host->busyluns); in acornscsi_kick()
764 host->stats.removes += 1; in acornscsi_kick()
768 host->stats.writes += 1; in acornscsi_kick()
771 host->stats.reads += 1; in acornscsi_kick()
774 host->stats.miscs += 1; in acornscsi_kick()
783 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
785 * Params : host - interface that completed
788 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, in acornscsi_done() argument
794 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); in acornscsi_done()
796 host->stats.fins += 1; in acornscsi_done()
801 acornscsi_dma_cleanup(host); in acornscsi_done()
803 SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status; in acornscsi_done()
817 if (host->scsi.SCp.ptr && in acornscsi_done()
821 if (host->scsi.SCp.scsi_xferred < SCpnt->underflow || in acornscsi_done()
822 host->scsi.SCp.scsi_xferred != host->dma.transferred) in acornscsi_done()
838 if (host->dma.xfer_done) in acornscsi_done()
855 acornscsi_dumpdma(host, "done"); in acornscsi_done()
856 acornscsi_dumplog(host, SCpnt->device->id); in acornscsi_done()
863 panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no); in acornscsi_done()
866 (u8)(SCpnt->device->lun & 0x7), host->busyluns); in acornscsi_done()
870 printk("scsi%d: null command in acornscsi_done", host->host->host_no); in acornscsi_done()
872 host->scsi.phase = PHASE_IDLE; in acornscsi_done()
883 void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length) in acornscsi_data_updateptr() argument
889 host->dma.xfer_done = 1; in acornscsi_data_updateptr()
893 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
896 * Params : host - host to transfer from
898 * start_addr - host mem address
903 void acornscsi_data_read(AS_Host *host, char *ptr, in acornscsi_data_read() argument
912 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_read()
922 __acornscsi_in(host->base + (offset << 1), ptr, this_len); in acornscsi_data_read()
931 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_read()
934 writeb(host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_read()
938 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
941 * Params : host - host to transfer from
943 * start_addr - host mem address
948 void acornscsi_data_write(AS_Host *host, char *ptr, in acornscsi_data_write() argument
957 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_write()
967 __acornscsi_out(host->base + (offset << 1), ptr, this_len); in acornscsi_data_write()
976 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_write()
979 writeb(host->card.page_reg, host->fast + PAGE_REG); in acornscsi_data_write()
987 * Prototype: void acornscsi_dmastop(AS_Host *host)
989 * Params : host - host on which to stop DMA
994 void acornscsi_dma_stop(AS_Host *host) in acornscsi_dma_stop() argument
996 dmac_write(host, DMAC_MASKREG, MASK_ON); in acornscsi_dma_stop()
997 dmac_clearintr(host); in acornscsi_dma_stop()
1000 DBG(host->SCpnt, acornscsi_dumpdma(host, "stop")); in acornscsi_dma_stop()
1005 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1007 * Params : host - host to setup
1013 void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) in acornscsi_dma_setup() argument
1017 host->dma.direction = direction; in acornscsi_dma_setup()
1019 dmac_write(host, DMAC_MASKREG, MASK_ON); in acornscsi_dma_setup()
1023 if (NO_WRITE & (1 << host->SCpnt->device->id)) { in acornscsi_dma_setup()
1025 host->host->host_no, acornscsi_target(host)); in acornscsi_dma_setup()
1036 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2); in acornscsi_dma_setup()
1038 host->dma.start_addr = address = host->dma.free_addr; in acornscsi_dma_setup()
1039 host->dma.free_addr = (host->dma.free_addr + length) & in acornscsi_dma_setup()
1046 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr, in acornscsi_dma_setup()
1050 dmac_write(host, DMAC_TXCNTLO, length); in acornscsi_dma_setup()
1051 dmac_write(host, DMAC_TXCNTHI, length >> 8); in acornscsi_dma_setup()
1052 dmac_write(host, DMAC_TXADRLO, address); in acornscsi_dma_setup()
1053 dmac_write(host, DMAC_TXADRMD, address >> 8); in acornscsi_dma_setup()
1054 dmac_write(host, DMAC_TXADRHI, 0); in acornscsi_dma_setup()
1055 dmac_write(host, DMAC_MODECON, mode); in acornscsi_dma_setup()
1056 dmac_write(host, DMAC_MASKREG, MASK_OFF); in acornscsi_dma_setup()
1059 DBG(host->SCpnt, acornscsi_dumpdma(host, "strt")); in acornscsi_dma_setup()
1061 host->dma.xfer_setup = 1; in acornscsi_dma_setup()
1066 * Function: void acornscsi_dma_cleanup(AS_Host *host)
1067 * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
1068 * Params : host - host to finish
1074 void acornscsi_dma_cleanup(AS_Host *host) in acornscsi_dma_cleanup() argument
1076 dmac_write(host, DMAC_MASKREG, MASK_ON); in acornscsi_dma_cleanup()
1077 dmac_clearintr(host); in acornscsi_dma_cleanup()
1082 if (host->dma.xfer_required) { in acornscsi_dma_cleanup()
1083 host->dma.xfer_required = 0; in acornscsi_dma_cleanup()
1084 if (host->dma.direction == DMA_IN) in acornscsi_dma_cleanup()
1085 acornscsi_data_read(host, host->dma.xfer_ptr, in acornscsi_dma_cleanup()
1086 host->dma.xfer_start, host->dma.xfer_length); in acornscsi_dma_cleanup()
1092 if (host->dma.xfer_setup) { in acornscsi_dma_cleanup()
1095 host->dma.xfer_setup = 0; in acornscsi_dma_cleanup()
1098 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi")); in acornscsi_dma_cleanup()
1104 transferred = dmac_address(host) - host->dma.start_addr; in acornscsi_dma_cleanup()
1105 host->dma.transferred += transferred; in acornscsi_dma_cleanup()
1107 if (host->dma.direction == DMA_IN) in acornscsi_dma_cleanup()
1108 acornscsi_data_read(host, host->scsi.SCp.ptr, in acornscsi_dma_cleanup()
1109 host->dma.start_addr, transferred); in acornscsi_dma_cleanup()
1114 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred); in acornscsi_dma_cleanup()
1116 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo")); in acornscsi_dma_cleanup()
1122 * Function: void acornscsi_dmacintr(AS_Host *host)
1124 * Params : host - host to process
1132 void acornscsi_dma_intr(AS_Host *host) in acornscsi_dma_intr() argument
1137 DBG(host->SCpnt, acornscsi_dumpdma(host, "inti")); in acornscsi_dma_intr()
1140 dmac_write(host, DMAC_MASKREG, MASK_ON); in acornscsi_dma_intr()
1141 dmac_clearintr(host); in acornscsi_dma_intr()
1146 transferred = dmac_address(host) - host->dma.start_addr; in acornscsi_dma_intr()
1147 host->dma.transferred += transferred; in acornscsi_dma_intr()
1152 if (host->dma.direction == DMA_IN) { in acornscsi_dma_intr()
1153 host->dma.xfer_start = host->dma.start_addr; in acornscsi_dma_intr()
1154 host->dma.xfer_length = transferred; in acornscsi_dma_intr()
1155 host->dma.xfer_ptr = host->scsi.SCp.ptr; in acornscsi_dma_intr()
1156 host->dma.xfer_required = 1; in acornscsi_dma_intr()
1159 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred); in acornscsi_dma_intr()
1164 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2); in acornscsi_dma_intr()
1166 host->dma.start_addr = address = host->dma.free_addr; in acornscsi_dma_intr()
1167 host->dma.free_addr = (host->dma.free_addr + length) & in acornscsi_dma_intr()
1173 if (host->dma.direction == DMA_OUT) in acornscsi_dma_intr()
1174 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr, in acornscsi_dma_intr()
1178 dmac_write(host, DMAC_TXCNTLO, length); in acornscsi_dma_intr()
1179 dmac_write(host, DMAC_TXCNTHI, length >> 8); in acornscsi_dma_intr()
1180 dmac_write(host, DMAC_TXADRLO, address); in acornscsi_dma_intr()
1181 dmac_write(host, DMAC_TXADRMD, address >> 8); in acornscsi_dma_intr()
1182 dmac_write(host, DMAC_TXADRHI, 0); in acornscsi_dma_intr()
1183 dmac_write(host, DMAC_MASKREG, MASK_OFF); in acornscsi_dma_intr()
1186 DBG(host->SCpnt, acornscsi_dumpdma(host, "into")); in acornscsi_dma_intr()
1189 host->dma.xfer_setup = 0; in acornscsi_dma_intr()
1197 if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) { in acornscsi_dma_intr()
1198 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_dma_intr()
1200 dmac_write(host, DMAC_TXCNTLO, 0); in acornscsi_dma_intr()
1201 dmac_write(host, DMAC_TXCNTHI, 0); in acornscsi_dma_intr()
1202 dmac_write(host, DMAC_TXADRLO, 0); in acornscsi_dma_intr()
1203 dmac_write(host, DMAC_TXADRMD, 0); in acornscsi_dma_intr()
1204 dmac_write(host, DMAC_TXADRHI, 0); in acornscsi_dma_intr()
1205 dmac_write(host, DMAC_MASKREG, MASK_OFF); in acornscsi_dma_intr()
1212 * Function: void acornscsi_dma_xfer(AS_Host *host)
1214 * Params : host - host to process
1217 void acornscsi_dma_xfer(AS_Host *host) in acornscsi_dma_xfer() argument
1219 host->dma.xfer_required = 0; in acornscsi_dma_xfer()
1221 if (host->dma.direction == DMA_IN) in acornscsi_dma_xfer()
1222 acornscsi_data_read(host, host->dma.xfer_ptr, in acornscsi_dma_xfer()
1223 host->dma.xfer_start, host->dma.xfer_length); in acornscsi_dma_xfer()
1227 * Function: void acornscsi_dma_adjust(AS_Host *host)
1230 * Params : host - host to adjust DMA count for
1233 void acornscsi_dma_adjust(AS_Host *host) in acornscsi_dma_adjust() argument
1235 if (host->dma.xfer_setup) { in acornscsi_dma_adjust()
1238 DBG(host->SCpnt, acornscsi_dumpdma(host, "adji")); in acornscsi_dma_adjust()
1243 * host->scsi.SCp.scsi_xferred is the number of bytes in acornscsi_dma_adjust()
1245 * host->dma.transferred is the number of bytes transferred in acornscsi_dma_adjust()
1246 * over DMA since host->dma.start_addr was last set. in acornscsi_dma_adjust()
1248 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred in acornscsi_dma_adjust()
1249 * - host->dma.transferred in acornscsi_dma_adjust()
1251 transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred; in acornscsi_dma_adjust()
1254 host->host->host_no, acornscsi_target(host), transferred); in acornscsi_dma_adjust()
1256 host->dma.xfer_setup = 0; in acornscsi_dma_adjust()
1258 transferred += host->dma.start_addr; in acornscsi_dma_adjust()
1259 dmac_write(host, DMAC_TXADRLO, transferred); in acornscsi_dma_adjust()
1260 dmac_write(host, DMAC_TXADRMD, transferred >> 8); in acornscsi_dma_adjust()
1261 dmac_write(host, DMAC_TXADRHI, transferred >> 16); in acornscsi_dma_adjust()
1263 DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo")); in acornscsi_dma_adjust()
1274 acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout) in acornscsi_write_pio() argument
1280 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_write_pio()
1285 sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]); in acornscsi_write_pio()
1299 * Function: void acornscsi_sendcommand(AS_Host *host)
1301 * Params : host - host which is connected to target
1304 acornscsi_sendcommand(AS_Host *host) in acornscsi_sendcommand() argument
1306 struct scsi_cmnd *SCpnt = host->SCpnt; in acornscsi_sendcommand()
1308 sbic_arm_write(host, SBIC_TRANSCNTH, 0); in acornscsi_sendcommand()
1309 sbic_arm_writenext(host, 0); in acornscsi_sendcommand()
1310 sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command); in acornscsi_sendcommand()
1312 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); in acornscsi_sendcommand()
1314 if (acornscsi_write_pio(host, SCpnt->cmnd, in acornscsi_sendcommand()
1315 (int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000)) in acornscsi_sendcommand()
1316 printk("scsi%d: timeout while sending command\n", host->host->host_no); in acornscsi_sendcommand()
1318 host->scsi.phase = PHASE_COMMAND; in acornscsi_sendcommand()
1322 void acornscsi_sendmessage(AS_Host *host) in acornscsi_sendmessage() argument
1324 unsigned int message_length = msgqueue_msglength(&host->scsi.msgs); in acornscsi_sendmessage()
1330 host->host->host_no, acornscsi_target(host)); in acornscsi_sendmessage()
1335 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); in acornscsi_sendmessage()
1337 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1"); in acornscsi_sendmessage()
1339 sbic_arm_write(host, SBIC_DATA, NOP); in acornscsi_sendmessage()
1341 host->scsi.last_message = NOP; in acornscsi_sendmessage()
1348 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); in acornscsi_sendmessage()
1349 msg = msgqueue_getmsg(&host->scsi.msgs, 0); in acornscsi_sendmessage()
1351 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2"); in acornscsi_sendmessage()
1353 sbic_arm_write(host, SBIC_DATA, msg->msg[0]); in acornscsi_sendmessage()
1355 host->scsi.last_message = msg->msg[0]; in acornscsi_sendmessage()
1370 sbic_arm_write(host, SBIC_TRANSCNTH, 0); in acornscsi_sendmessage()
1371 sbic_arm_writenext(host, 0); in acornscsi_sendmessage()
1372 sbic_arm_writenext(host, message_length); in acornscsi_sendmessage()
1373 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); in acornscsi_sendmessage()
1376 while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) { in acornscsi_sendmessage()
1382 if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000)) in acornscsi_sendmessage()
1383 printk("scsi%d: timeout while sending message\n", host->host->host_no); in acornscsi_sendmessage()
1385 host->scsi.last_message = msg->msg[0]; in acornscsi_sendmessage()
1387 host->scsi.last_message |= msg->msg[2] << 8; in acornscsi_sendmessage()
1400 * Function: void acornscsi_readstatusbyte(AS_Host *host)
1402 * Params : host - host connected to target
1405 void acornscsi_readstatusbyte(AS_Host *host) in acornscsi_readstatusbyte() argument
1407 acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT); in acornscsi_readstatusbyte()
1408 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte"); in acornscsi_readstatusbyte()
1409 host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA); in acornscsi_readstatusbyte()
1413 * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
1415 * Params : host - host connected to target
1418 unsigned char acornscsi_readmessagebyte(AS_Host *host) in acornscsi_readmessagebyte() argument
1422 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); in acornscsi_readmessagebyte()
1424 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte"); in acornscsi_readmessagebyte()
1426 message = sbic_arm_read(host, SBIC_DATA); in acornscsi_readmessagebyte()
1429 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte"); in acornscsi_readmessagebyte()
1431 sbic_arm_read(host, SBIC_SSR); in acornscsi_readmessagebyte()
1437 * Function: void acornscsi_message(AS_Host *host)
1439 * Params : host - host connected to target
1442 void acornscsi_message(AS_Host *host) in acornscsi_message() argument
1448 message[msgidx] = acornscsi_readmessagebyte(host); in acornscsi_message()
1464 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); in acornscsi_message()
1467 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack"); in acornscsi_message()
1468 sbic_arm_read(host, SBIC_SSR); in acornscsi_message()
1474 host->host->host_no, acornscsi_target(host)); in acornscsi_message()
1479 if (host->scsi.phase == PHASE_RECONNECTED) { in acornscsi_message()
1487 host->scsi.reconnected.tag = message[1]; in acornscsi_message()
1488 if (acornscsi_reconnect_finish(host)) in acornscsi_message()
1489 host->scsi.phase = PHASE_MSGIN; in acornscsi_message()
1496 if (host->scsi.phase != PHASE_STATUSIN) { in acornscsi_message()
1498 host->host->host_no, acornscsi_target(host)); in acornscsi_message()
1499 acornscsi_dumplog(host, host->SCpnt->device->id); in acornscsi_message()
1501 host->scsi.phase = PHASE_DONE; in acornscsi_message()
1502 host->scsi.SCp.Message = message[0]; in acornscsi_message()
1512 acornscsi_dma_cleanup(host); in acornscsi_message()
1513 host->SCpnt->SCp = host->scsi.SCp; in acornscsi_message()
1514 host->SCpnt->SCp.sent_command = 0; in acornscsi_message()
1515 host->scsi.phase = PHASE_MSGIN; in acornscsi_message()
1528 acornscsi_dma_cleanup(host); in acornscsi_message()
1529 host->scsi.SCp = host->SCpnt->SCp; in acornscsi_message()
1530 host->scsi.phase = PHASE_MSGIN; in acornscsi_message()
1543 acornscsi_dma_cleanup(host); in acornscsi_message()
1544 host->scsi.phase = PHASE_DISCONNECT; in acornscsi_message()
1555 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) in acornscsi_message()
1556 host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE; in acornscsi_message()
1562 if (msgqueue_msglength(&host->scsi.msgs)) in acornscsi_message()
1563 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); in acornscsi_message()
1565 switch (host->scsi.last_message) { in acornscsi_message()
1577 host->host->host_no, acornscsi_target(host)); in acornscsi_message()
1578 host->SCpnt->device->simple_tags = 0; in acornscsi_message()
1579 set_bit(host->SCpnt->device->id * 8 + in acornscsi_message()
1580 (u8)(host->SCpnt->device->lun & 0x7), host->busyluns); in acornscsi_message()
1588 host->host->host_no, acornscsi_target(host)); in acornscsi_message()
1589 host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA; in acornscsi_message()
1590 host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS; in acornscsi_message()
1591 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); in acornscsi_message()
1606 host->host->host_no, acornscsi_target(host), in acornscsi_message()
1614 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) { in acornscsi_message()
1621 host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED; in acornscsi_message()
1623 host->host->host_no, acornscsi_target(host), in acornscsi_message()
1625 host->device[host->SCpnt->device->id].sync_xfer = in acornscsi_message()
1633 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); in acornscsi_message()
1636 msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3, in acornscsi_message()
1638 host->device[host->SCpnt->device->id].sync_xfer = in acornscsi_message()
1641 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); in acornscsi_message()
1654 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); in acornscsi_message()
1655 msgqueue_flush(&host->scsi.msgs); in acornscsi_message()
1656 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT); in acornscsi_message()
1663 host->host->host_no, acornscsi_target(host), in acornscsi_message()
1665 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); in acornscsi_message()
1666 msgqueue_flush(&host->scsi.msgs); in acornscsi_message()
1667 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT); in acornscsi_message()
1668 host->scsi.phase = PHASE_MSGIN; in acornscsi_message()
1671 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); in acornscsi_message()
1675 * Function: int acornscsi_buildmessages(AS_Host *host)
1676 * Purpose : build the connection messages for a host
1677 * Params : host - host to add messages to
1680 void acornscsi_buildmessages(AS_Host *host) in acornscsi_buildmessages() argument
1685 msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET); in acornscsi_buildmessages()
1690 msgqueue_addmsg(&host->scsi.msgs, 1, in acornscsi_buildmessages()
1691 IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok, in acornscsi_buildmessages()
1692 host->SCpnt->device->lun)); in acornscsi_buildmessages()
1697 acornscsi_abortcmd(host->SCpnt->tag); in acornscsi_buildmessages()
1703 if (host->SCpnt->tag) { in acornscsi_buildmessages()
1706 if (host->SCpnt->cmnd[0] == REQUEST_SENSE || in acornscsi_buildmessages()
1707 host->SCpnt->cmnd[0] == TEST_UNIT_READY || in acornscsi_buildmessages()
1708 host->SCpnt->cmnd[0] == INQUIRY) in acornscsi_buildmessages()
1712 msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag); in acornscsi_buildmessages()
1717 if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) { in acornscsi_buildmessages()
1718 host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST; in acornscsi_buildmessages()
1719 msgqueue_addmsg(&host->scsi.msgs, 5, in acornscsi_buildmessages()
1727 * Function: int acornscsi_starttransfer(AS_Host *host)
1729 * Params : host - host to which target is connected
1733 int acornscsi_starttransfer(AS_Host *host) in acornscsi_starttransfer() argument
1737 if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) { in acornscsi_starttransfer()
1739 host->host->host_no, acornscsi_target(host)); in acornscsi_starttransfer()
1743 residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred; in acornscsi_starttransfer()
1745 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); in acornscsi_starttransfer()
1746 sbic_arm_writenext(host, residual >> 16); in acornscsi_starttransfer()
1747 sbic_arm_writenext(host, residual >> 8); in acornscsi_starttransfer()
1748 sbic_arm_writenext(host, residual); in acornscsi_starttransfer()
1749 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); in acornscsi_starttransfer()
1757 * Function : acornscsi_reconnect(AS_Host *host)
1759 * Params : host - host specific data
1765 int acornscsi_reconnect(AS_Host *host) in acornscsi_reconnect() argument
1769 target = sbic_arm_read(host, SBIC_SOURCEID); in acornscsi_reconnect()
1774 host->host->host_no); in acornscsi_reconnect()
1778 if (host->SCpnt && !host->scsi.disconnectable) { in acornscsi_reconnect()
1781 host->host->host_no, target, host->SCpnt->device->id); in acornscsi_reconnect()
1782 host->SCpnt = NULL; in acornscsi_reconnect()
1785 lun = sbic_arm_read(host, SBIC_DATA) & 7; in acornscsi_reconnect()
1787 host->scsi.reconnected.target = target; in acornscsi_reconnect()
1788 host->scsi.reconnected.lun = lun; in acornscsi_reconnect()
1789 host->scsi.reconnected.tag = 0; in acornscsi_reconnect()
1791 if (host->scsi.disconnectable && host->SCpnt && in acornscsi_reconnect()
1792 host->SCpnt->device->id == target && host->SCpnt->device->lun == lun) in acornscsi_reconnect()
1795 if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun)) in acornscsi_reconnect()
1798 ADD_STATUS(target, 0x81, host->scsi.phase, 0); in acornscsi_reconnect()
1801 host->scsi.phase = PHASE_RECONNECTED; in acornscsi_reconnect()
1806 host->host->host_no, '0' + target); in acornscsi_reconnect()
1807 acornscsi_dumplog(host, target); in acornscsi_reconnect()
1808 acornscsi_abortcmd(host, 0); in acornscsi_reconnect()
1809 if (host->SCpnt) { in acornscsi_reconnect()
1810 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); in acornscsi_reconnect()
1811 host->SCpnt = NULL; in acornscsi_reconnect()
1814 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); in acornscsi_reconnect()
1819 * Function: int acornscsi_reconnect_finish(AS_Host *host)
1821 * Params : host - host to complete
1825 int acornscsi_reconnect_finish(AS_Host *host) in acornscsi_reconnect_finish() argument
1827 if (host->scsi.disconnectable && host->SCpnt) { in acornscsi_reconnect_finish()
1828 host->scsi.disconnectable = 0; in acornscsi_reconnect_finish()
1829 if (host->SCpnt->device->id == host->scsi.reconnected.target && in acornscsi_reconnect_finish()
1830 host->SCpnt->device->lun == host->scsi.reconnected.lun && in acornscsi_reconnect_finish()
1831 host->SCpnt->tag == host->scsi.reconnected.tag) { in acornscsi_reconnect_finish()
1833 DBG(host->SCpnt, printk("scsi%d.%c: reconnected", in acornscsi_reconnect_finish()
1834 host->host->host_no, acornscsi_target(host))); in acornscsi_reconnect_finish()
1837 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); in acornscsi_reconnect_finish()
1839 DBG(host->SCpnt, printk("scsi%d.%c: had to move command " in acornscsi_reconnect_finish()
1841 host->host->host_no, acornscsi_target(host))); in acornscsi_reconnect_finish()
1843 host->SCpnt = NULL; in acornscsi_reconnect_finish()
1846 if (!host->SCpnt) { in acornscsi_reconnect_finish()
1847 host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected, in acornscsi_reconnect_finish()
1848 host->scsi.reconnected.target, in acornscsi_reconnect_finish()
1849 host->scsi.reconnected.lun, in acornscsi_reconnect_finish()
1850 host->scsi.reconnected.tag); in acornscsi_reconnect_finish()
1852 DBG(host->SCpnt, printk("scsi%d.%c: had to get command", in acornscsi_reconnect_finish()
1853 host->host->host_no, acornscsi_target(host))); in acornscsi_reconnect_finish()
1857 if (!host->SCpnt) in acornscsi_reconnect_finish()
1858 acornscsi_abortcmd(host, host->scsi.reconnected.tag); in acornscsi_reconnect_finish()
1863 host->scsi.SCp = host->SCpnt->SCp; in acornscsi_reconnect_finish()
1866 host->scsi.SCp.ptr, host->scsi.SCp.this_residual); in acornscsi_reconnect_finish()
1873 host->dma.transferred = host->scsi.SCp.scsi_xferred; in acornscsi_reconnect_finish()
1875 return host->SCpnt != NULL; in acornscsi_reconnect_finish()
1879 * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1881 * Params : host - host on which disconnect occurred
1884 void acornscsi_disconnect_unexpected(AS_Host *host) in acornscsi_disconnect_unexpected() argument
1887 host->host->host_no, acornscsi_target(host)); in acornscsi_disconnect_unexpected()
1889 acornscsi_dumplog(host, 8); in acornscsi_disconnect_unexpected()
1892 acornscsi_done(host, &host->SCpnt, DID_ERROR); in acornscsi_disconnect_unexpected()
1896 * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
1898 * Params : host - host with connected command to abort
1902 void acornscsi_abortcmd(AS_Host *host, unsigned char tag) in acornscsi_abortcmd() argument
1904 host->scsi.phase = PHASE_ABORTED; in acornscsi_abortcmd()
1905 sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN); in acornscsi_abortcmd()
1907 msgqueue_flush(&host->scsi.msgs); in acornscsi_abortcmd()
1910 msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag); in acornscsi_abortcmd()
1913 msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); in acornscsi_abortcmd()
1920 * Function: int acornscsi_sbicintr(AS_Host *host)
1922 * Params : host - host to process
1928 intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) in acornscsi_sbicintr() argument
1932 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_sbicintr()
1936 ssr = sbic_arm_read(host, SBIC_SSR); in acornscsi_sbicintr()
1939 print_sbic_status(asr, ssr, host->scsi.phase); in acornscsi_sbicintr()
1942 ADD_STATUS(8, ssr, host->scsi.phase, in_irq); in acornscsi_sbicintr()
1944 if (host->SCpnt && !host->scsi.disconnectable) in acornscsi_sbicintr()
1945 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq); in acornscsi_sbicintr()
1950 host->host->host_no); in acornscsi_sbicintr()
1952 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); in acornscsi_sbicintr()
1953 sbic_arm_write(host, SBIC_CMND, CMND_RESET); in acornscsi_sbicintr()
1957 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); in acornscsi_sbicintr()
1958 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); in acornscsi_sbicintr()
1959 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); in acornscsi_sbicintr()
1960 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); in acornscsi_sbicintr()
1961 msgqueue_flush(&host->scsi.msgs); in acornscsi_sbicintr()
1965 acornscsi_disconnect_unexpected(host); in acornscsi_sbicintr()
1969 switch (host->scsi.phase) { in acornscsi_sbicintr()
1974 host->scsi.phase = PHASE_CONNECTED; in acornscsi_sbicintr()
1975 msgqueue_flush(&host->scsi.msgs); in acornscsi_sbicintr()
1976 host->dma.transferred = host->scsi.SCp.scsi_xferred; in acornscsi_sbicintr()
1978 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_sbicintr()
1981 ssr = sbic_arm_read(host, SBIC_SSR); in acornscsi_sbicintr()
1982 ADD_STATUS(8, ssr, host->scsi.phase, 1); in acornscsi_sbicintr()
1983 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1); in acornscsi_sbicintr()
1988 acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT); in acornscsi_sbicintr()
1993 host->origSCpnt = host->SCpnt; in acornscsi_sbicintr()
1994 host->SCpnt = NULL; in acornscsi_sbicintr()
1995 msgqueue_flush(&host->scsi.msgs); in acornscsi_sbicintr()
1996 acornscsi_reconnect(host); in acornscsi_sbicintr()
2001 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2002 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2003 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2013 acornscsi_sendcommand(host); in acornscsi_sbicintr()
2018 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2019 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2025 host->scsi.phase = PHASE_MSGOUT; in acornscsi_sbicintr()
2026 acornscsi_buildmessages(host); in acornscsi_sbicintr()
2027 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2032 acornscsi_done(host, &host->SCpnt, DID_ERROR); in acornscsi_sbicintr()
2037 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2038 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2039 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2052 acornscsi_sendcommand(host); in acornscsi_sbicintr()
2058 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2059 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2064 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2070 acornscsi_message(host); in acornscsi_sbicintr()
2075 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2076 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2084 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) in acornscsi_sbicintr()
2085 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2086 acornscsi_dma_setup(host, DMA_OUT); in acornscsi_sbicintr()
2087 if (!acornscsi_starttransfer(host)) in acornscsi_sbicintr()
2088 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2089 host->scsi.phase = PHASE_DATAOUT; in acornscsi_sbicintr()
2094 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) in acornscsi_sbicintr()
2095 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2096 acornscsi_dma_setup(host, DMA_IN); in acornscsi_sbicintr()
2097 if (!acornscsi_starttransfer(host)) in acornscsi_sbicintr()
2098 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2099 host->scsi.phase = PHASE_DATAIN; in acornscsi_sbicintr()
2104 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2105 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2110 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2115 acornscsi_message(host); in acornscsi_sbicintr()
2120 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2121 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2127 host->scsi.disconnectable = 1; in acornscsi_sbicintr()
2128 host->scsi.reconnected.tag = 0; in acornscsi_sbicintr()
2129 host->scsi.phase = PHASE_IDLE; in acornscsi_sbicintr()
2130 host->stats.disconnects += 1; in acornscsi_sbicintr()
2133 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2134 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2140 acornscsi_reconnect(host); in acornscsi_sbicintr()
2143 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2144 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2157 if (ssr != 0x8f && !acornscsi_reconnect_finish(host)) in acornscsi_sbicintr()
2159 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq); in acornscsi_sbicintr()
2164 acornscsi_dma_setup(host, DMA_OUT); in acornscsi_sbicintr()
2165 if (!acornscsi_starttransfer(host)) in acornscsi_sbicintr()
2166 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2167 host->scsi.phase = PHASE_DATAOUT; in acornscsi_sbicintr()
2173 acornscsi_dma_setup(host, DMA_IN); in acornscsi_sbicintr()
2174 if (!acornscsi_starttransfer(host)) in acornscsi_sbicintr()
2175 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2176 host->scsi.phase = PHASE_DATAIN; in acornscsi_sbicintr()
2181 acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */ in acornscsi_sbicintr()
2187 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2188 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2194 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2198 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ in acornscsi_sbicintr()
2203 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2204 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2216 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2223 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2224 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2225 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2226 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2227 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2234 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2235 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2236 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2237 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2244 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2245 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2246 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2247 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ in acornscsi_sbicintr()
2252 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2253 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2265 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_sbicintr()
2272 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2273 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2274 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2275 acornscsi_dma_adjust(host); in acornscsi_sbicintr()
2276 acornscsi_readstatusbyte(host); in acornscsi_sbicintr()
2277 host->scsi.phase = PHASE_STATUSIN; in acornscsi_sbicintr()
2284 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2285 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2286 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2287 acornscsi_dma_adjust(host); in acornscsi_sbicintr()
2288 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2295 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - in acornscsi_sbicintr()
2296 acornscsi_sbic_xfcount(host); in acornscsi_sbicintr()
2297 acornscsi_dma_stop(host); in acornscsi_sbicintr()
2298 acornscsi_dma_adjust(host); in acornscsi_sbicintr()
2299 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ in acornscsi_sbicintr()
2304 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2305 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2314 acornscsi_message(host); in acornscsi_sbicintr()
2320 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2325 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2326 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2336 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2343 acornscsi_message(host); in acornscsi_sbicintr()
2348 host->host->host_no, acornscsi_target(host)); in acornscsi_sbicintr()
2349 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2350 acornscsi_done(host, &host->SCpnt, DID_ERROR); in acornscsi_sbicintr()
2355 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2356 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2363 acornscsi_done(host, &host->SCpnt, DID_OK); in acornscsi_sbicintr()
2368 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2373 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2374 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2381 if (host->SCpnt) in acornscsi_sbicintr()
2382 acornscsi_done(host, &host->SCpnt, DID_ABORT); in acornscsi_sbicintr()
2384 clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun, in acornscsi_sbicintr()
2385 host->busyluns); in acornscsi_sbicintr()
2386 host->scsi.phase = PHASE_IDLE; in acornscsi_sbicintr()
2394 acornscsi_sendmessage(host); in acornscsi_sbicintr()
2399 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2400 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2406 host->host->host_no, acornscsi_target(host), ssr); in acornscsi_sbicintr()
2407 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); in acornscsi_sbicintr()
2421 AS_Host *host = (AS_Host *)dev_id; in acornscsi_intr() local
2429 iostatus = readb(host->fast + INT_REG); in acornscsi_intr()
2432 acornscsi_dma_intr(host); in acornscsi_intr()
2433 iostatus = readb(host->fast + INT_REG); in acornscsi_intr()
2437 ret = acornscsi_sbicintr(host, in_irq); in acornscsi_intr()
2444 if (host->dma.xfer_required) in acornscsi_intr()
2445 acornscsi_dma_xfer(host); in acornscsi_intr()
2448 ret = acornscsi_kick(host); in acornscsi_intr()
2470 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; in acornscsi_queuecmd_lck() local
2475 host->host->host_no, SCpnt); in acornscsi_queuecmd_lck()
2482 host->host->host_no, '0' + SCpnt->device->id); in acornscsi_queuecmd_lck()
2499 host->stats.queues += 1; in acornscsi_queuecmd_lck()
2504 if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) { in acornscsi_queuecmd_lck()
2510 if (host->scsi.phase == PHASE_IDLE) in acornscsi_queuecmd_lck()
2511 acornscsi_kick(host); in acornscsi_queuecmd_lck()
2548 * Purpose : abort a command on this host
2552 static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) in acornscsi_do_abort() argument
2556 if (queue_remove_cmd(&host->queues.issue, SCpnt)) { in acornscsi_do_abort()
2567 } else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) { in acornscsi_do_abort()
2579 } else if (host->SCpnt == SCpnt) { in acornscsi_do_abort()
2587 switch (host->scsi.phase) { in acornscsi_do_abort()
2597 if (host->scsi.disconnectable) { in acornscsi_do_abort()
2598 host->scsi.disconnectable = 0; in acornscsi_do_abort()
2599 host->SCpnt = NULL; in acornscsi_do_abort()
2610 sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT); in acornscsi_do_abort()
2611 host->SCpnt = NULL; in acornscsi_do_abort()
2616 acornscsi_abortcmd(host, host->SCpnt->tag); in acornscsi_do_abort()
2620 } else if (host->origSCpnt == SCpnt) { in acornscsi_do_abort()
2627 host->origSCpnt = NULL; in acornscsi_do_abort()
2640 * Purpose : abort a command on this host
2646 AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata; in acornscsi_abort() local
2649 host->stats.aborts += 1; in acornscsi_abort()
2654 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_abort()
2655 ssr = sbic_arm_read(host, SBIC_SSR); in acornscsi_abort()
2658 print_sbic_status(asr, ssr, host->scsi.phase); in acornscsi_abort()
2659 acornscsi_dumplog(host, SCpnt->device->id); in acornscsi_abort()
2663 printk("scsi%d: ", host->host->host_no); in acornscsi_abort()
2665 switch (acornscsi_do_abort(host, SCpnt)) { in acornscsi_abort()
2676 (u8)(SCpnt->device->lun & 0x7), host->busyluns); in acornscsi_abort()
2708 acornscsi_dumplog(host, SCpnt->device->id); in acornscsi_abort()
2721 * Purpose : reset a command on this host/reset this host
2727 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; in acornscsi_host_reset() local
2730 host->stats.resets += 1; in acornscsi_host_reset()
2736 asr = sbic_arm_read(host, SBIC_ASR); in acornscsi_host_reset()
2737 ssr = sbic_arm_read(host, SBIC_SSR); in acornscsi_host_reset()
2740 print_sbic_status(asr, ssr, host->scsi.phase); in acornscsi_host_reset()
2742 acornscsi_dumplog(host, devidx); in acornscsi_host_reset()
2746 acornscsi_dma_stop(host); in acornscsi_host_reset()
2749 * do hard reset. This resets all devices on this host, and so we in acornscsi_host_reset()
2752 acornscsi_resetcard(host); in acornscsi_host_reset()
2754 while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL) in acornscsi_host_reset()
2765 * Function: char *acornscsi_info(struct Scsi_Host *host)
2767 * Params : host - host to give information on
2771 char *acornscsi_info(struct Scsi_Host *host) in acornscsi_info() argument
2787 , host->hostt->name, host->io_port, host->irq, in acornscsi_info()
2796 AS_Host *host; in acornscsi_show_info() local
2798 host = (AS_Host *)instance->hostdata; in acornscsi_show_info()
2813 host->base + SBIC_REGIDX, host->scsi.irq); in acornscsi_show_info()
2816 host->base + DMAC_OFFSET, host->scsi.irq); in acornscsi_show_info()
2825 host->stats.queues, host->stats.removes, in acornscsi_show_info()
2826 host->stats.fins, host->stats.reads, in acornscsi_show_info()
2827 host->stats.writes, host->stats.miscs, in acornscsi_show_info()
2828 host->stats.disconnects, host->stats.aborts, in acornscsi_show_info()
2829 host->stats.resets); in acornscsi_show_info()
2835 statptr = host->status_ptr[devidx] - 10; in acornscsi_show_info()
2840 prev = host->status[devidx][statptr].when; in acornscsi_show_info()
2842 for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) { in acornscsi_show_info()
2843 if (host->status[devidx][statptr].when) { in acornscsi_show_info()
2845 host->status[devidx][statptr].irq ? '-' : ' ', in acornscsi_show_info()
2846 host->status[devidx][statptr].ph, in acornscsi_show_info()
2847 host->status[devidx][statptr].ssr, in acornscsi_show_info()
2848 (host->status[devidx][statptr].when - prev) < 100 ? in acornscsi_show_info()
2849 (host->status[devidx][statptr].when - prev) : 99); in acornscsi_show_info()
2850 prev = host->status[devidx][statptr].when; in acornscsi_show_info()
2867 if (host->device[scd->id].sync_xfer & 15) in acornscsi_show_info()
2869 host->device[scd->id].sync_xfer & 15, in acornscsi_show_info()
2870 acornscsi_getperiod(host->device[scd->id].sync_xfer)); in acornscsi_show_info()
2896 struct Scsi_Host *host; in acornscsi_probe() local
2904 host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host)); in acornscsi_probe()
2905 if (!host) { in acornscsi_probe()
2910 ashost = (AS_Host *)host->hostdata; in acornscsi_probe()
2919 host->irq = ec->irq; in acornscsi_probe()
2920 ashost->host = host; in acornscsi_probe()
2921 ashost->scsi.irq = host->irq; in acornscsi_probe()
2926 ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi", ashost); in acornscsi_probe()
2929 host->host_no, ashost->scsi.irq, ret); in acornscsi_probe()
2940 ret = scsi_add_host(host, &ec->dev); in acornscsi_probe()
2944 scsi_scan_host(host); in acornscsi_probe()
2948 free_irq(host->irq, ashost); in acornscsi_probe()
2955 scsi_host_put(host); in acornscsi_probe()
2964 struct Scsi_Host *host = ecard_get_drvdata(ec); in acornscsi_remove() local
2965 AS_Host *ashost = (AS_Host *)host->hostdata; in acornscsi_remove()
2968 scsi_remove_host(host); in acornscsi_remove()
2975 free_irq(host->irq, ashost); in acornscsi_remove()
2982 scsi_host_put(host); in acornscsi_remove()