Lines Matching refs:host

179 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
181 static int acornscsi_reconnect_finish(AS_Host *host);
182 static void acornscsi_dma_cleanup(AS_Host *host);
183 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
198 static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
200 writeb(reg, host->base + SBIC_REGIDX);
201 writeb(value, host->base + SBIC_REGVAL);
204 static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
207 return readl(host->base + SBIC_REGIDX) & 255;
208 writeb(reg, host->base + SBIC_REGIDX);
209 return readl(host->base + SBIC_REGVAL) & 255;
212 #define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
213 #define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
216 #define dmac_read(host,reg) \
217 readb((host)->base + DMAC_OFFSET + ((reg) << 2))
219 #define dmac_write(host,reg,value) \
220 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
222 #define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
224 static inline unsigned int dmac_address(AS_Host *host)
226 return dmac_read(host, DMAC_TXADRHI) << 16 |
227 dmac_read(host, DMAC_TXADRMD) << 8 |
228 dmac_read(host, DMAC_TXADRLO);
232 void acornscsi_dumpdma(AS_Host *host, char *where)
236 mode = dmac_read(host, DMAC_MODECON);
237 addr = dmac_address(host);
238 len = dmac_read(host, DMAC_TXCNTHI) << 8 |
239 dmac_read(host, DMAC_TXCNTLO);
242 host->host->host_no, where,
244 dmac_read(host, DMAC_MASKREG));
246 printk("DMA @%06x, ", host->dma.start_addr);
247 printk("BH @%p +%04x, ", host->scsi.SCp.ptr,
248 host->scsi.SCp.this_residual);
249 printk("DT @+%04x ST @+%04x", host->dma.transferred,
250 host->scsi.SCp.scsi_xferred);
256 unsigned long acornscsi_sbic_xfcount(AS_Host *host)
260 length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16;
261 length |= sbic_arm_readnext(host) << 8;
262 length |= sbic_arm_readnext(host);
268 acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg)
273 asr = sbic_arm_read(host, SBIC_ASR);
281 printk("scsi%d: timeout while %s\n", host->host->host_no, msg);
287 int acornscsi_sbic_issuecmd(AS_Host *host, int command)
289 if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command"))
292 sbic_arm_write(host, SBIC_CMND, command);
313 void acornscsi_resetcard(AS_Host *host)
318 host->card.page_reg = 0x80;
319 writeb(host->card.page_reg, host->fast + PAGE_REG);
324 host->card.page_reg = 0;
325 writeb(host->card.page_reg, host->fast + PAGE_REG);
332 if (readb(host->fast + INT_REG) & 8)
339 host->host->host_no);
341 sbic_arm_read(host, SBIC_ASR);
342 sbic_arm_read(host, SBIC_SSR);
345 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
346 sbic_arm_write(host, SBIC_CMND, CMND_RESET);
353 if (readb(host->fast + INT_REG) & 8)
360 host->host->host_no);
362 sbic_arm_read(host, SBIC_ASR);
363 if (sbic_arm_read(host, SBIC_SSR) != 0x01)
365 host->host->host_no);
367 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
368 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
369 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
370 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
372 host->card.page_reg = 0x40;
373 writeb(host->card.page_reg, host->fast + PAGE_REG);
376 dmac_write(host, DMAC_INIT, 0);
378 dmac_write(host, DMAC_INIT, INIT_8BIT);
379 dmac_write(host, DMAC_CHANNEL, CHANNEL_0);
380 dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0);
381 dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1);
384 host->SCpnt = NULL;
385 host->scsi.phase = PHASE_IDLE;
386 host->scsi.disconnectable = 0;
388 memset(host->busyluns, 0, sizeof(host->busyluns));
391 host->device[i].sync_state = SYNC_NEGOCIATE;
392 host->device[i].disconnect_ok = 1;
498 acornscsi_dumplogline(AS_Host *host, int target, int line)
503 ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT;
510 prev = host->status[target][ptr].when;
512 for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
515 if (!host->status[target][ptr].when)
520 printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ',
521 host->status[target][ptr].ph);
525 printk(" %02X", host->status[target][ptr].ssr);
529 time_diff = host->status[target][ptr].when - prev;
530 prev = host->status[target][ptr].when;
545 void acornscsi_dumplog(AS_Host *host, int target)
548 acornscsi_dumplogline(host, target, 0);
549 acornscsi_dumplogline(host, target, 1);
550 acornscsi_dumplogline(host, target, 2);
560 char acornscsi_target(AS_Host *host)
562 if (host->SCpnt)
563 return '0' + host->SCpnt->device->id;
690 * Function: acornscsi_kick(AS_Host *host)
692 * Params : host - host to send command to
697 intr_ret_t acornscsi_kick(AS_Host *host)
703 SCpnt = host->origSCpnt;
704 host->origSCpnt = NULL;
708 SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns);
715 if (host->scsi.disconnectable && host->SCpnt) {
716 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
717 host->scsi.disconnectable = 0;
719 DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n",
720 host->host->host_no, acornscsi_target(host)));
722 host->SCpnt = NULL;
729 if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) {
730 sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id);
731 sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN);
735 * claim host busy - all of these must happen atomically wrt
738 host->scsi.phase = PHASE_CONNECTING;
739 host->SCpnt = SCpnt;
740 host->scsi.SCp = SCpnt->SCp;
741 host->dma.xfer_setup = 0;
742 host->dma.xfer_required = 0;
743 host->dma.xfer_done = 0;
747 host->host->host_no, '0' + SCpnt->device->id,
764 (u8)(SCpnt->device->lun & 0x07), host->busyluns);
766 host->stats.removes += 1;
770 host->stats.writes += 1;
773 host->stats.reads += 1;
776 host->stats.miscs += 1;
785 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
787 * Params : host - interface that completed
790 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
796 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
798 host->stats.fins += 1;
803 acornscsi_dma_cleanup(host);
805 SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status;
819 if (host->scsi.SCp.ptr &&
823 if (host->scsi.SCp.scsi_xferred < SCpnt->underflow ||
824 host->scsi.SCp.scsi_xferred != host->dma.transferred)
840 if (host->dma.xfer_done)
854 host->host->host_no, SCpnt->result);
856 acornscsi_dumpdma(host, "done");
857 acornscsi_dumplog(host, SCpnt->device->id);
865 panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);
868 (u8)(SCpnt->device->lun & 0x7), host->busyluns);
872 printk("scsi%d: null command in acornscsi_done", host->host->host_no);
874 host->scsi.phase = PHASE_IDLE;
885 void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length)
891 host->dma.xfer_done = 1;
895 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr,
898 * Params : host - host to transfer from
900 * start_addr - host mem address
905 void acornscsi_data_read(AS_Host *host, char *ptr,
914 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
924 __acornscsi_in(host->base + (offset << 1), ptr, this_len);
933 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
936 writeb(host->card.page_reg, host->fast + PAGE_REG);
940 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr,
943 * Params : host - host to transfer from
945 * start_addr - host mem address
950 void acornscsi_data_write(AS_Host *host, char *ptr,
959 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
969 __acornscsi_out(host->base + (offset << 1), ptr, this_len);
978 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
981 writeb(host->card.page_reg, host->fast + PAGE_REG);
989 * Prototype: void acornscsi_dmastop(AS_Host *host)
991 * Params : host - host on which to stop DMA
996 void acornscsi_dma_stop(AS_Host *host)
998 dmac_write(host, DMAC_MASKREG, MASK_ON);
999 dmac_clearintr(host);
1002 DBG(host->SCpnt, acornscsi_dumpdma(host, "stop"));
1007 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1009 * Params : host - host to setup
1015 void acornscsi_dma_setup(AS_Host *host, dmadir_t direction)
1019 host->dma.direction = direction;
1021 dmac_write(host, DMAC_MASKREG, MASK_ON);
1025 if (NO_WRITE & (1 << host->SCpnt->device->id)) {
1027 host->host->host_no, acornscsi_target(host));
1038 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1040 host->dma.start_addr = address = host->dma.free_addr;
1041 host->dma.free_addr = (host->dma.free_addr + length) &
1048 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1052 dmac_write(host, DMAC_TXCNTLO, length);
1053 dmac_write(host, DMAC_TXCNTHI, length >> 8);
1054 dmac_write(host, DMAC_TXADRLO, address);
1055 dmac_write(host, DMAC_TXADRMD, address >> 8);
1056 dmac_write(host, DMAC_TXADRHI, 0);
1057 dmac_write(host, DMAC_MODECON, mode);
1058 dmac_write(host, DMAC_MASKREG, MASK_OFF);
1061 DBG(host->SCpnt, acornscsi_dumpdma(host, "strt"));
1063 host->dma.xfer_setup = 1;
1068 * Function: void acornscsi_dma_cleanup(AS_Host *host)
1069 * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct
1070 * Params : host - host to finish
1076 void acornscsi_dma_cleanup(AS_Host *host)
1078 dmac_write(host, DMAC_MASKREG, MASK_ON);
1079 dmac_clearintr(host);
1084 if (host->dma.xfer_required) {
1085 host->dma.xfer_required = 0;
1086 if (host->dma.direction == DMA_IN)
1087 acornscsi_data_read(host, host->dma.xfer_ptr,
1088 host->dma.xfer_start, host->dma.xfer_length);
1094 if (host->dma.xfer_setup) {
1097 host->dma.xfer_setup = 0;
1100 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi"));
1106 transferred = dmac_address(host) - host->dma.start_addr;
1107 host->dma.transferred += transferred;
1109 if (host->dma.direction == DMA_IN)
1110 acornscsi_data_read(host, host->scsi.SCp.ptr,
1111 host->dma.start_addr, transferred);
1116 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1118 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo"));
1124 * Function: void acornscsi_dmacintr(AS_Host *host)
1126 * Params : host - host to process
1134 void acornscsi_dma_intr(AS_Host *host)
1139 DBG(host->SCpnt, acornscsi_dumpdma(host, "inti"));
1142 dmac_write(host, DMAC_MASKREG, MASK_ON);
1143 dmac_clearintr(host);
1148 transferred = dmac_address(host) - host->dma.start_addr;
1149 host->dma.transferred += transferred;
1154 if (host->dma.direction == DMA_IN) {
1155 host->dma.xfer_start = host->dma.start_addr;
1156 host->dma.xfer_length = transferred;
1157 host->dma.xfer_ptr = host->scsi.SCp.ptr;
1158 host->dma.xfer_required = 1;
1161 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred);
1166 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2);
1168 host->dma.start_addr = address = host->dma.free_addr;
1169 host->dma.free_addr = (host->dma.free_addr + length) &
1175 if (host->dma.direction == DMA_OUT)
1176 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr,
1180 dmac_write(host, DMAC_TXCNTLO, length);
1181 dmac_write(host, DMAC_TXCNTHI, length >> 8);
1182 dmac_write(host, DMAC_TXADRLO, address);
1183 dmac_write(host, DMAC_TXADRMD, address >> 8);
1184 dmac_write(host, DMAC_TXADRHI, 0);
1185 dmac_write(host, DMAC_MASKREG, MASK_OFF);
1188 DBG(host->SCpnt, acornscsi_dumpdma(host, "into"));
1191 host->dma.xfer_setup = 0;
1199 if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) {
1200 acornscsi_abortcmd(host, host->SCpnt->tag);
1202 dmac_write(host, DMAC_TXCNTLO, 0);
1203 dmac_write(host, DMAC_TXCNTHI, 0);
1204 dmac_write(host, DMAC_TXADRLO, 0);
1205 dmac_write(host, DMAC_TXADRMD, 0);
1206 dmac_write(host, DMAC_TXADRHI, 0);
1207 dmac_write(host, DMAC_MASKREG, MASK_OFF);
1214 * Function: void acornscsi_dma_xfer(AS_Host *host)
1216 * Params : host - host to process
1219 void acornscsi_dma_xfer(AS_Host *host)
1221 host->dma.xfer_required = 0;
1223 if (host->dma.direction == DMA_IN)
1224 acornscsi_data_read(host, host->dma.xfer_ptr,
1225 host->dma.xfer_start, host->dma.xfer_length);
1229 * Function: void acornscsi_dma_adjust(AS_Host *host)
1232 * Params : host - host to adjust DMA count for
1235 void acornscsi_dma_adjust(AS_Host *host)
1237 if (host->dma.xfer_setup) {
1240 DBG(host->SCpnt, acornscsi_dumpdma(host, "adji"));
1245 * host->scsi.SCp.scsi_xferred is the number of bytes
1247 * host->dma.transferred is the number of bytes transferred
1248 * over DMA since host->dma.start_addr was last set.
1250 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred
1251 * - host->dma.transferred
1253 transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred;
1256 host->host->host_no, acornscsi_target(host), transferred);
1258 host->dma.xfer_setup = 0;
1260 transferred += host->dma.start_addr;
1261 dmac_write(host, DMAC_TXADRLO, transferred);
1262 dmac_write(host, DMAC_TXADRMD, transferred >> 8);
1263 dmac_write(host, DMAC_TXADRHI, transferred >> 16);
1265 DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo"));
1276 acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout)
1282 asr = sbic_arm_read(host, SBIC_ASR);
1287 sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]);
1301 * Function: void acornscsi_sendcommand(AS_Host *host)
1303 * Params : host - host which is connected to target
1306 acornscsi_sendcommand(AS_Host *host)
1308 struct scsi_cmnd *SCpnt = host->SCpnt;
1310 sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1311 sbic_arm_writenext(host, 0);
1312 sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command);
1314 acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1316 if (acornscsi_write_pio(host, SCpnt->cmnd,
1317 (int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000))
1318 printk("scsi%d: timeout while sending command\n", host->host->host_no);
1320 host->scsi.phase = PHASE_COMMAND;
1324 void acornscsi_sendmessage(AS_Host *host)
1326 unsigned int message_length = msgqueue_msglength(&host->scsi.msgs);
1332 host->host->host_no, acornscsi_target(host));
1337 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1339 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1");
1341 sbic_arm_write(host, SBIC_DATA, NOP);
1343 host->scsi.last_message = NOP;
1350 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1351 msg = msgqueue_getmsg(&host->scsi.msgs, 0);
1353 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2");
1355 sbic_arm_write(host, SBIC_DATA, msg->msg[0]);
1357 host->scsi.last_message = msg->msg[0];
1372 sbic_arm_write(host, SBIC_TRANSCNTH, 0);
1373 sbic_arm_writenext(host, 0);
1374 sbic_arm_writenext(host, message_length);
1375 acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1378 while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
1384 if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
1385 printk("scsi%d: timeout while sending message\n", host->host->host_no);
1387 host->scsi.last_message = msg->msg[0];
1389 host->scsi.last_message |= msg->msg[2] << 8;
1402 * Function: void acornscsi_readstatusbyte(AS_Host *host)
1404 * Params : host - host connected to target
1407 void acornscsi_readstatusbyte(AS_Host *host)
1409 acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT);
1410 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte");
1411 host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA);
1415 * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host)
1417 * Params : host - host connected to target
1420 unsigned char acornscsi_readmessagebyte(AS_Host *host)
1424 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT);
1426 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte");
1428 message = sbic_arm_read(host, SBIC_DATA);
1431 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte");
1433 sbic_arm_read(host, SBIC_SSR);
1439 * Function: void acornscsi_message(AS_Host *host)
1441 * Params : host - host connected to target
1444 void acornscsi_message(AS_Host *host)
1450 message[msgidx] = acornscsi_readmessagebyte(host);
1466 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1469 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack");
1470 sbic_arm_read(host, SBIC_SSR);
1476 host->host->host_no, acornscsi_target(host));
1481 if (host->scsi.phase == PHASE_RECONNECTED) {
1489 host->scsi.reconnected.tag = message[1];
1490 if (acornscsi_reconnect_finish(host))
1491 host->scsi.phase = PHASE_MSGIN;
1498 if (host->scsi.phase != PHASE_STATUSIN) {
1500 host->host->host_no, acornscsi_target(host));
1501 acornscsi_dumplog(host, host->SCpnt->device->id);
1503 host->scsi.phase = PHASE_DONE;
1504 host->scsi.SCp.Message = message[0];
1514 acornscsi_dma_cleanup(host);
1515 host->SCpnt->SCp = host->scsi.SCp;
1516 host->SCpnt->SCp.sent_command = 0;
1517 host->scsi.phase = PHASE_MSGIN;
1530 acornscsi_dma_cleanup(host);
1531 host->scsi.SCp = host->SCpnt->SCp;
1532 host->scsi.phase = PHASE_MSGIN;
1545 acornscsi_dma_cleanup(host);
1546 host->scsi.phase = PHASE_DISCONNECT;
1557 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST)
1558 host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE;
1564 if (msgqueue_msglength(&host->scsi.msgs))
1565 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1567 switch (host->scsi.last_message) {
1579 host->host->host_no, acornscsi_target(host));
1580 host->SCpnt->device->simple_tags = 0;
1581 set_bit(host->SCpnt->device->id * 8 +
1582 (u8)(host->SCpnt->device->lun & 0x7), host->busyluns);
1590 host->host->host_no, acornscsi_target(host));
1591 host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA;
1592 host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS;
1593 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1608 host->host->host_no, acornscsi_target(host),
1616 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) {
1623 host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED;
1625 host->host->host_no, acornscsi_target(host),
1627 host->device[host->SCpnt->device->id].sync_xfer =
1635 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1638 msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3,
1640 host->device[host->SCpnt->device->id].sync_xfer =
1643 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1656 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1657 msgqueue_flush(&host->scsi.msgs);
1658 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1665 host->host->host_no, acornscsi_target(host),
1667 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
1668 msgqueue_flush(&host->scsi.msgs);
1669 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT);
1670 host->scsi.phase = PHASE_MSGIN;
1673 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1677 * Function: int acornscsi_buildmessages(AS_Host *host)
1678 * Purpose : build the connection messages for a host
1679 * Params : host - host to add messages to
1682 void acornscsi_buildmessages(AS_Host *host)
1687 msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET);
1692 msgqueue_addmsg(&host->scsi.msgs, 1,
1693 IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok,
1694 host->SCpnt->device->lun));
1699 acornscsi_abortcmd(host->SCpnt->tag);
1705 if (host->SCpnt->tag) {
1708 if (host->SCpnt->cmnd[0] == REQUEST_SENSE ||
1709 host->SCpnt->cmnd[0] == TEST_UNIT_READY ||
1710 host->SCpnt->cmnd[0] == INQUIRY)
1714 msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag);
1719 if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) {
1720 host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST;
1721 msgqueue_addmsg(&host->scsi.msgs, 5,
1729 * Function: int acornscsi_starttransfer(AS_Host *host)
1731 * Params : host - host to which target is connected
1735 int acornscsi_starttransfer(AS_Host *host)
1739 if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) {
1741 host->host->host_no, acornscsi_target(host));
1745 residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred;
1747 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer);
1748 sbic_arm_writenext(host, residual >> 16);
1749 sbic_arm_writenext(host, residual >> 8);
1750 sbic_arm_writenext(host, residual);
1751 acornscsi_sbic_issuecmd(host, CMND_XFERINFO);
1759 * Function : acornscsi_reconnect(AS_Host *host)
1761 * Params : host - host specific data
1767 int acornscsi_reconnect(AS_Host *host)
1771 target = sbic_arm_read(host, SBIC_SOURCEID);
1776 host->host->host_no);
1780 if (host->SCpnt && !host->scsi.disconnectable) {
1783 host->host->host_no, target, host->SCpnt->device->id);
1784 host->SCpnt = NULL;
1787 lun = sbic_arm_read(host, SBIC_DATA) & 7;
1789 host->scsi.reconnected.target = target;
1790 host->scsi.reconnected.lun = lun;
1791 host->scsi.reconnected.tag = 0;
1793 if (host->scsi.disconnectable && host->SCpnt &&
1794 host->SCpnt->device->id == target && host->SCpnt->device->lun == lun)
1797 if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun))
1800 ADD_STATUS(target, 0x81, host->scsi.phase, 0);
1803 host->scsi.phase = PHASE_RECONNECTED;
1808 host->host->host_no, '0' + target);
1809 acornscsi_dumplog(host, target);
1810 acornscsi_abortcmd(host, 0);
1811 if (host->SCpnt) {
1812 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1813 host->SCpnt = NULL;
1816 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK);
1821 * Function: int acornscsi_reconect_finish(AS_Host *host)
1823 * Params : host - host to complete
1827 int acornscsi_reconnect_finish(AS_Host *host)
1829 if (host->scsi.disconnectable && host->SCpnt) {
1830 host->scsi.disconnectable = 0;
1831 if (host->SCpnt->device->id == host->scsi.reconnected.target &&
1832 host->SCpnt->device->lun == host->scsi.reconnected.lun &&
1833 host->SCpnt->tag == host->scsi.reconnected.tag) {
1835 DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
1836 host->host->host_no, acornscsi_target(host)));
1839 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt);
1841 DBG(host->SCpnt, printk("scsi%d.%c: had to move command "
1843 host->host->host_no, acornscsi_target(host)));
1845 host->SCpnt = NULL;
1848 if (!host->SCpnt) {
1849 host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected,
1850 host->scsi.reconnected.target,
1851 host->scsi.reconnected.lun,
1852 host->scsi.reconnected.tag);
1854 DBG(host->SCpnt, printk("scsi%d.%c: had to get command",
1855 host->host->host_no, acornscsi_target(host)));
1859 if (!host->SCpnt)
1860 acornscsi_abortcmd(host, host->scsi.reconnected.tag);
1865 host->scsi.SCp = host->SCpnt->SCp;
1868 host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
1875 host->dma.transferred = host->scsi.SCp.scsi_xferred;
1877 return host->SCpnt != NULL;
1881 * Function: void acornscsi_disconnect_unexpected(AS_Host *host)
1883 * Params : host - host on which disconnect occurred
1886 void acornscsi_disconnect_unexpected(AS_Host *host)
1889 host->host->host_no, acornscsi_target(host));
1891 acornscsi_dumplog(host, 8);
1894 acornscsi_done(host, &host->SCpnt, DID_ERROR);
1898 * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag)
1900 * Params : host - host with connected command to abort
1904 void acornscsi_abortcmd(AS_Host *host, unsigned char tag)
1906 host->scsi.phase = PHASE_ABORTED;
1907 sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN);
1909 msgqueue_flush(&host->scsi.msgs);
1912 msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag);
1915 msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
1922 * Function: int acornscsi_sbicintr(AS_Host *host)
1924 * Params : host - host to process
1930 intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
1934 asr = sbic_arm_read(host, SBIC_ASR);
1938 ssr = sbic_arm_read(host, SBIC_SSR);
1941 print_sbic_status(asr, ssr, host->scsi.phase);
1944 ADD_STATUS(8, ssr, host->scsi.phase, in_irq);
1946 if (host->SCpnt && !host->scsi.disconnectable)
1947 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
1952 host->host->host_no);
1954 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id);
1955 sbic_arm_write(host, SBIC_CMND, CMND_RESET);
1959 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI);
1960 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME);
1961 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA);
1962 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
1963 msgqueue_flush(&host->scsi.msgs);
1967 acornscsi_disconnect_unexpected(host);
1971 switch (host->scsi.phase) {
1976 host->scsi.phase = PHASE_CONNECTED;
1977 msgqueue_flush(&host->scsi.msgs);
1978 host->dma.transferred = host->scsi.SCp.scsi_xferred;
1980 asr = sbic_arm_read(host, SBIC_ASR);
1983 ssr = sbic_arm_read(host, SBIC_SSR);
1984 ADD_STATUS(8, ssr, host->scsi.phase, 1);
1985 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1);
1990 acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT);
1995 host->origSCpnt = host->SCpnt;
1996 host->SCpnt = NULL;
1997 msgqueue_flush(&host->scsi.msgs);
1998 acornscsi_reconnect(host);
2003 host->host->host_no, acornscsi_target(host), ssr);
2004 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2005 acornscsi_abortcmd(host, host->SCpnt->tag);
2015 acornscsi_sendcommand(host);
2020 acornscsi_readstatusbyte(host);
2021 host->scsi.phase = PHASE_STATUSIN;
2027 host->scsi.phase = PHASE_MSGOUT;
2028 acornscsi_buildmessages(host);
2029 acornscsi_sendmessage(host);
2034 acornscsi_done(host, &host->SCpnt, DID_ERROR);
2039 host->host->host_no, acornscsi_target(host), ssr);
2040 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2041 acornscsi_abortcmd(host, host->SCpnt->tag);
2054 acornscsi_sendcommand(host);
2060 acornscsi_readstatusbyte(host);
2061 host->scsi.phase = PHASE_STATUSIN;
2066 acornscsi_sendmessage(host);
2072 acornscsi_message(host);
2077 host->host->host_no, acornscsi_target(host), ssr);
2078 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2086 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2087 acornscsi_abortcmd(host, host->SCpnt->tag);
2088 acornscsi_dma_setup(host, DMA_OUT);
2089 if (!acornscsi_starttransfer(host))
2090 acornscsi_abortcmd(host, host->SCpnt->tag);
2091 host->scsi.phase = PHASE_DATAOUT;
2096 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)
2097 acornscsi_abortcmd(host, host->SCpnt->tag);
2098 acornscsi_dma_setup(host, DMA_IN);
2099 if (!acornscsi_starttransfer(host))
2100 acornscsi_abortcmd(host, host->SCpnt->tag);
2101 host->scsi.phase = PHASE_DATAIN;
2106 acornscsi_readstatusbyte(host);
2107 host->scsi.phase = PHASE_STATUSIN;
2112 acornscsi_sendmessage(host);
2117 acornscsi_message(host);
2122 host->host->host_no, acornscsi_target(host), ssr);
2123 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2129 host->scsi.disconnectable = 1;
2130 host->scsi.reconnected.tag = 0;
2131 host->scsi.phase = PHASE_IDLE;
2132 host->stats.disconnects += 1;
2135 host->host->host_no, acornscsi_target(host), ssr);
2136 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2142 acornscsi_reconnect(host);
2145 host->host->host_no, acornscsi_target(host), ssr);
2146 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2159 if (ssr != 0x8f && !acornscsi_reconnect_finish(host))
2161 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq);
2166 acornscsi_dma_setup(host, DMA_OUT);
2167 if (!acornscsi_starttransfer(host))
2168 acornscsi_abortcmd(host, host->SCpnt->tag);
2169 host->scsi.phase = PHASE_DATAOUT;
2175 acornscsi_dma_setup(host, DMA_IN);
2176 if (!acornscsi_starttransfer(host))
2177 acornscsi_abortcmd(host, host->SCpnt->tag);
2178 host->scsi.phase = PHASE_DATAIN;
2183 acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */
2189 acornscsi_readstatusbyte(host);
2190 host->scsi.phase = PHASE_STATUSIN;
2196 acornscsi_sendmessage(host);
2200 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2205 host->host->host_no, acornscsi_target(host), ssr);
2206 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2218 acornscsi_abortcmd(host, host->SCpnt->tag);
2225 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2226 acornscsi_sbic_xfcount(host);
2227 acornscsi_dma_stop(host);
2228 acornscsi_readstatusbyte(host);
2229 host->scsi.phase = PHASE_STATUSIN;
2236 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2237 acornscsi_sbic_xfcount(host);
2238 acornscsi_dma_stop(host);
2239 acornscsi_sendmessage(host);
2246 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2247 acornscsi_sbic_xfcount(host);
2248 acornscsi_dma_stop(host);
2249 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2254 host->host->host_no, acornscsi_target(host), ssr);
2255 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2267 acornscsi_abortcmd(host, host->SCpnt->tag);
2274 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2275 acornscsi_sbic_xfcount(host);
2276 acornscsi_dma_stop(host);
2277 acornscsi_dma_adjust(host);
2278 acornscsi_readstatusbyte(host);
2279 host->scsi.phase = PHASE_STATUSIN;
2286 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2287 acornscsi_sbic_xfcount(host);
2288 acornscsi_dma_stop(host);
2289 acornscsi_dma_adjust(host);
2290 acornscsi_sendmessage(host);
2297 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) -
2298 acornscsi_sbic_xfcount(host);
2299 acornscsi_dma_stop(host);
2300 acornscsi_dma_adjust(host);
2301 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */
2306 host->host->host_no, acornscsi_target(host), ssr);
2307 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2316 acornscsi_message(host);
2322 acornscsi_sendmessage(host);
2327 host->host->host_no, acornscsi_target(host), ssr);
2328 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2338 acornscsi_sendmessage(host);
2345 acornscsi_message(host);
2350 host->host->host_no, acornscsi_target(host));
2351 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2352 acornscsi_done(host, &host->SCpnt, DID_ERROR);
2357 host->host->host_no, acornscsi_target(host), ssr);
2358 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2365 acornscsi_done(host, &host->SCpnt, DID_OK);
2370 acornscsi_sendmessage(host);
2375 host->host->host_no, acornscsi_target(host), ssr);
2376 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2383 if (host->SCpnt)
2384 acornscsi_done(host, &host->SCpnt, DID_ABORT);
2386 clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun,
2387 host->busyluns);
2388 host->scsi.phase = PHASE_IDLE;
2396 acornscsi_sendmessage(host);
2401 host->host->host_no, acornscsi_target(host), ssr);
2402 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2408 host->host->host_no, acornscsi_target(host), ssr);
2409 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8);
2423 AS_Host *host = (AS_Host *)dev_id;
2431 iostatus = readb(host->fast + INT_REG);
2434 acornscsi_dma_intr(host);
2435 iostatus = readb(host->fast + INT_REG);
2439 ret = acornscsi_sbicintr(host, in_irq);
2446 if (host->dma.xfer_required)
2447 acornscsi_dma_xfer(host);
2450 ret = acornscsi_kick(host);
2472 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2477 host->host->host_no, SCpnt);
2484 host->host->host_no, '0' + SCpnt->device->id);
2501 host->stats.queues += 1;
2506 if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
2512 if (host->scsi.phase == PHASE_IDLE)
2513 acornscsi_kick(host);
2550 * Purpose : abort a command on this host
2554 static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
2558 if (queue_remove_cmd(&host->queues.issue, SCpnt)) {
2569 } else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) {
2581 } else if (host->SCpnt == SCpnt) {
2589 switch (host->scsi.phase) {
2599 if (host->scsi.disconnectable) {
2600 host->scsi.disconnectable = 0;
2601 host->SCpnt = NULL;
2612 sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT);
2613 host->SCpnt = NULL;
2618 acornscsi_abortcmd(host, host->SCpnt->tag);
2622 } else if (host->origSCpnt == SCpnt) {
2629 host->origSCpnt = NULL;
2642 * Purpose : abort a command on this host
2648 AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
2651 host->stats.aborts += 1;
2656 asr = sbic_arm_read(host, SBIC_ASR);
2657 ssr = sbic_arm_read(host, SBIC_SSR);
2660 print_sbic_status(asr, ssr, host->scsi.phase);
2661 acornscsi_dumplog(host, SCpnt->device->id);
2665 printk("scsi%d: ", host->host->host_no);
2667 switch (acornscsi_do_abort(host, SCpnt)) {
2678 (u8)(SCpnt->device->lun & 0x7), host->busyluns);
2710 acornscsi_dumplog(host, SCpnt->device->id);
2723 * Purpose : reset a command on this host/reset this host
2729 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
2732 host->stats.resets += 1;
2738 asr = sbic_arm_read(host, SBIC_ASR);
2739 ssr = sbic_arm_read(host, SBIC_SSR);
2742 print_sbic_status(asr, ssr, host->scsi.phase);
2743 acornscsi_dumplog(host, SCpnt->device->id);
2747 acornscsi_dma_stop(host);
2750 * do hard reset. This resets all devices on this host, and so we
2753 acornscsi_resetcard(host);
2755 while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL)
2766 * Function: char *acornscsi_info(struct Scsi_Host *host)
2768 * Params : host - host to give information on
2772 char *acornscsi_info(struct Scsi_Host *host)
2788 , host->hostt->name, host->io_port, host->irq,
2797 AS_Host *host;
2799 host = (AS_Host *)instance->hostdata;
2814 host->base + SBIC_REGIDX, host->scsi.irq);
2817 host->base + DMAC_OFFSET, host->scsi.irq);
2826 host->stats.queues, host->stats.removes,
2827 host->stats.fins, host->stats.reads,
2828 host->stats.writes, host->stats.miscs,
2829 host->stats.disconnects, host->stats.aborts,
2830 host->stats.resets);
2836 statptr = host->status_ptr[devidx] - 10;
2841 prev = host->status[devidx][statptr].when;
2843 for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) {
2844 if (host->status[devidx][statptr].when) {
2846 host->status[devidx][statptr].irq ? '-' : ' ',
2847 host->status[devidx][statptr].ph,
2848 host->status[devidx][statptr].ssr,
2849 (host->status[devidx][statptr].when - prev) < 100 ?
2850 (host->status[devidx][statptr].when - prev) : 99);
2851 prev = host->status[devidx][statptr].when;
2868 if (host->device[scd->id].sync_xfer & 15)
2870 host->device[scd->id].sync_xfer & 15,
2871 acornscsi_getperiod(host->device[scd->id].sync_xfer));
2897 struct Scsi_Host *host;
2905 host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
2906 if (!host) {
2911 ashost = (AS_Host *)host->hostdata;
2918 host->irq = ec->irq;
2919 ashost->host = host;
2920 ashost->scsi.irq = host->irq;
2925 ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi", ashost);
2928 host->host_no, ashost->scsi.irq, ret);
2939 ret = scsi_add_host(host, &ec->dev);
2943 scsi_scan_host(host);
2947 free_irq(host->irq, ashost);
2954 scsi_host_put(host);
2963 struct Scsi_Host *host = ecard_get_drvdata(ec);
2964 AS_Host *ashost = (AS_Host *)host->hostdata;
2967 scsi_remove_host(host);
2974 free_irq(host->irq, ashost);
2981 scsi_host_put(host);