0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/module.h>
0035 #include <linux/blkdev.h>
0036 #include <linux/kernel.h>
0037 #include <linux/string.h>
0038 #include <linux/ioport.h>
0039 #include <linux/proc_fs.h>
0040 #include <linux/delay.h>
0041 #include <linux/bitops.h>
0042 #include <linux/init.h>
0043 #include <linux/interrupt.h>
0044
0045 #include <asm/dma.h>
0046 #include <asm/io.h>
0047 #include <asm/irq.h>
0048 #include <asm/ecard.h>
0049
0050 #include <scsi/scsi.h>
0051 #include <scsi/scsi_cmnd.h>
0052 #include <scsi/scsi_dbg.h>
0053 #include <scsi/scsi_device.h>
0054 #include <scsi/scsi_eh.h>
0055 #include <scsi/scsi_host.h>
0056 #include <scsi/scsi_tcq.h>
0057 #include "fas216.h"
0058 #include "arm_scsi.h"
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 #define SCSI2_SYNC
0084
0085 #undef DEBUG_CONNECT
0086 #undef DEBUG_MESSAGES
0087
0088 #undef CHECK_STRUCTURE
0089
0090 #define LOG_CONNECT (1 << 0)
0091 #define LOG_BUSSERVICE (1 << 1)
0092 #define LOG_FUNCTIONDONE (1 << 2)
0093 #define LOG_MESSAGES (1 << 3)
0094 #define LOG_BUFFER (1 << 4)
0095 #define LOG_ERROR (1 << 8)
0096
0097 static int level_mask = LOG_ERROR;
0098
0099 module_param(level_mask, int, 0644);
0100
0101 #ifndef MODULE
0102 static int __init fas216_log_setup(char *str)
0103 {
0104 char *s;
0105
0106 level_mask = 0;
0107
0108 while ((s = strsep(&str, ",")) != NULL) {
0109 switch (s[0]) {
0110 case 'a':
0111 if (strcmp(s, "all") == 0)
0112 level_mask |= -1;
0113 break;
0114 case 'b':
0115 if (strncmp(s, "bus", 3) == 0)
0116 level_mask |= LOG_BUSSERVICE;
0117 if (strncmp(s, "buf", 3) == 0)
0118 level_mask |= LOG_BUFFER;
0119 break;
0120 case 'c':
0121 level_mask |= LOG_CONNECT;
0122 break;
0123 case 'e':
0124 level_mask |= LOG_ERROR;
0125 break;
0126 case 'm':
0127 level_mask |= LOG_MESSAGES;
0128 break;
0129 case 'n':
0130 if (strcmp(s, "none") == 0)
0131 level_mask = 0;
0132 break;
0133 case 's':
0134 level_mask |= LOG_FUNCTIONDONE;
0135 break;
0136 }
0137 }
0138 return 1;
0139 }
0140
0141 __setup("fas216_logging=", fas216_log_setup);
0142 #endif
0143
0144 static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg)
0145 {
0146 unsigned int off = reg << info->scsi.io_shift;
0147 return readb(info->scsi.io_base + off);
0148 }
0149
0150 static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val)
0151 {
0152 unsigned int off = reg << info->scsi.io_shift;
0153 writeb(val, info->scsi.io_base + off);
0154 }
0155
0156 static void fas216_dumpstate(FAS216_Info *info)
0157 {
0158 unsigned char is, stat, inst;
0159
0160 is = fas216_readb(info, REG_IS);
0161 stat = fas216_readb(info, REG_STAT);
0162 inst = fas216_readb(info, REG_INST);
0163
0164 printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X"
0165 " INST=%02X IS=%02X CFIS=%02X",
0166 fas216_readb(info, REG_CTCL),
0167 fas216_readb(info, REG_CTCM),
0168 fas216_readb(info, REG_CMD), stat, inst, is,
0169 fas216_readb(info, REG_CFIS));
0170 printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n",
0171 fas216_readb(info, REG_CNTL1),
0172 fas216_readb(info, REG_CNTL2),
0173 fas216_readb(info, REG_CNTL3),
0174 fas216_readb(info, REG_CTCH));
0175 }
0176
0177 static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix)
0178 {
0179 printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s",
0180 prefix, SCp->ptr, SCp->this_residual, SCp->buffer,
0181 SCp->buffers_residual, suffix);
0182 }
0183
0184 #ifdef CHECK_STRUCTURE
0185 static void fas216_dumpinfo(FAS216_Info *info)
0186 {
0187 static int used = 0;
0188 int i;
0189
0190 if (used++)
0191 return;
0192
0193 printk("FAS216_Info=\n");
0194 printk(" { magic_start=%lX host=%p SCpnt=%p origSCpnt=%p\n",
0195 info->magic_start, info->host, info->SCpnt,
0196 info->origSCpnt);
0197 printk(" scsi={ io_shift=%X irq=%X cfg={ %X %X %X %X }\n",
0198 info->scsi.io_shift, info->scsi.irq,
0199 info->scsi.cfg[0], info->scsi.cfg[1], info->scsi.cfg[2],
0200 info->scsi.cfg[3]);
0201 printk(" type=%p phase=%X\n",
0202 info->scsi.type, info->scsi.phase);
0203 print_SCp(&info->scsi.SCp, " SCp={ ", " }\n");
0204 printk(" msgs async_stp=%X disconnectable=%d aborting=%d }\n",
0205 info->scsi.async_stp,
0206 info->scsi.disconnectable, info->scsi.aborting);
0207 printk(" stats={ queues=%X removes=%X fins=%X reads=%X writes=%X miscs=%X\n"
0208 " disconnects=%X aborts=%X bus_resets=%X host_resets=%X}\n",
0209 info->stats.queues, info->stats.removes, info->stats.fins,
0210 info->stats.reads, info->stats.writes, info->stats.miscs,
0211 info->stats.disconnects, info->stats.aborts, info->stats.bus_resets,
0212 info->stats.host_resets);
0213 printk(" ifcfg={ clockrate=%X select_timeout=%X asyncperiod=%X sync_max_depth=%X }\n",
0214 info->ifcfg.clockrate, info->ifcfg.select_timeout,
0215 info->ifcfg.asyncperiod, info->ifcfg.sync_max_depth);
0216 for (i = 0; i < 8; i++) {
0217 printk(" busyluns[%d]=%08lx dev[%d]={ disconnect_ok=%d stp=%X sof=%X sync_state=%X }\n",
0218 i, info->busyluns[i], i,
0219 info->device[i].disconnect_ok, info->device[i].stp,
0220 info->device[i].sof, info->device[i].sync_state);
0221 }
0222 printk(" dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
0223 info->dma.transfer_type, info->dma.setup,
0224 info->dma.pseudo, info->dma.stop);
0225 printk(" internal_done=%X magic_end=%lX }\n",
0226 info->internal_done, info->magic_end);
0227 }
0228
0229 static void __fas216_checkmagic(FAS216_Info *info, const char *func)
0230 {
0231 int corruption = 0;
0232 if (info->magic_start != MAGIC) {
0233 printk(KERN_CRIT "FAS216 Error: magic at start corrupted\n");
0234 corruption++;
0235 }
0236 if (info->magic_end != MAGIC) {
0237 printk(KERN_CRIT "FAS216 Error: magic at end corrupted\n");
0238 corruption++;
0239 }
0240 if (corruption) {
0241 fas216_dumpinfo(info);
0242 panic("scsi memory space corrupted in %s", func);
0243 }
0244 }
0245 #define fas216_checkmagic(info) __fas216_checkmagic((info), __func__)
0246 #else
0247 #define fas216_checkmagic(info)
0248 #endif
0249
0250 static const char *fas216_bus_phase(int stat)
0251 {
0252 static const char *phases[] = {
0253 "DATA OUT", "DATA IN",
0254 "COMMAND", "STATUS",
0255 "MISC OUT", "MISC IN",
0256 "MESG OUT", "MESG IN"
0257 };
0258
0259 return phases[stat & STAT_BUSMASK];
0260 }
0261
0262 static const char *fas216_drv_phase(FAS216_Info *info)
0263 {
0264 static const char *phases[] = {
0265 [PHASE_IDLE] = "idle",
0266 [PHASE_SELECTION] = "selection",
0267 [PHASE_COMMAND] = "command",
0268 [PHASE_DATAOUT] = "data out",
0269 [PHASE_DATAIN] = "data in",
0270 [PHASE_MSGIN] = "message in",
0271 [PHASE_MSGIN_DISCONNECT]= "disconnect",
0272 [PHASE_MSGOUT_EXPECT] = "expect message out",
0273 [PHASE_MSGOUT] = "message out",
0274 [PHASE_STATUS] = "status",
0275 [PHASE_DONE] = "done",
0276 };
0277
0278 if (info->scsi.phase < ARRAY_SIZE(phases) &&
0279 phases[info->scsi.phase])
0280 return phases[info->scsi.phase];
0281 return "???";
0282 }
0283
0284 static char fas216_target(FAS216_Info *info)
0285 {
0286 if (info->SCpnt)
0287 return '0' + info->SCpnt->device->id;
0288 else
0289 return 'H';
0290 }
0291
0292 static void
0293 fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
0294 {
0295 static char buf[1024];
0296
0297 vsnprintf(buf, sizeof(buf), fmt, ap);
0298 printk("scsi%d.%c: %s", info->host->host_no, target, buf);
0299 }
0300
0301 static void fas216_log_command(FAS216_Info *info, int level,
0302 struct scsi_cmnd *SCpnt, char *fmt, ...)
0303 {
0304 va_list args;
0305
0306 if (level != 0 && !(level & level_mask))
0307 return;
0308
0309 va_start(args, fmt);
0310 fas216_do_log(info, '0' + SCpnt->device->id, fmt, args);
0311 va_end(args);
0312
0313 scsi_print_command(SCpnt);
0314 }
0315
0316 static void
0317 fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...)
0318 {
0319 va_list args;
0320
0321 if (level != 0 && !(level & level_mask))
0322 return;
0323
0324 if (target < 0)
0325 target = 'H';
0326 else
0327 target += '0';
0328
0329 va_start(args, fmt);
0330 fas216_do_log(info, target, fmt, args);
0331 va_end(args);
0332
0333 printk("\n");
0334 }
0335
0336 static void fas216_log(FAS216_Info *info, int level, char *fmt, ...)
0337 {
0338 va_list args;
0339
0340 if (level != 0 && !(level & level_mask))
0341 return;
0342
0343 va_start(args, fmt);
0344 fas216_do_log(info, fas216_target(info), fmt, args);
0345 va_end(args);
0346
0347 printk("\n");
0348 }
0349
0350 #define PH_SIZE 32
0351
0352 static struct { int stat, ssr, isr, ph; } ph_list[PH_SIZE];
0353 static int ph_ptr;
0354
0355 static void add_debug_list(int stat, int ssr, int isr, int ph)
0356 {
0357 ph_list[ph_ptr].stat = stat;
0358 ph_list[ph_ptr].ssr = ssr;
0359 ph_list[ph_ptr].isr = isr;
0360 ph_list[ph_ptr].ph = ph;
0361
0362 ph_ptr = (ph_ptr + 1) & (PH_SIZE-1);
0363 }
0364
0365 static struct { int command; void *from; } cmd_list[8];
0366 static int cmd_ptr;
0367
0368 static void fas216_cmd(FAS216_Info *info, unsigned int command)
0369 {
0370 cmd_list[cmd_ptr].command = command;
0371 cmd_list[cmd_ptr].from = __builtin_return_address(0);
0372
0373 cmd_ptr = (cmd_ptr + 1) & 7;
0374
0375 fas216_writeb(info, REG_CMD, command);
0376 }
0377
0378 static void print_debug_list(void)
0379 {
0380 int i;
0381
0382 i = ph_ptr;
0383
0384 printk(KERN_ERR "SCSI IRQ trail\n");
0385 do {
0386 printk(" %02x:%02x:%02x:%1x",
0387 ph_list[i].stat, ph_list[i].ssr,
0388 ph_list[i].isr, ph_list[i].ph);
0389 i = (i + 1) & (PH_SIZE - 1);
0390 if (((i ^ ph_ptr) & 7) == 0)
0391 printk("\n");
0392 } while (i != ph_ptr);
0393 if ((i ^ ph_ptr) & 7)
0394 printk("\n");
0395
0396 i = cmd_ptr;
0397 printk(KERN_ERR "FAS216 commands: ");
0398 do {
0399 printk("%02x:%p ", cmd_list[i].command, cmd_list[i].from);
0400 i = (i + 1) & 7;
0401 } while (i != cmd_ptr);
0402 printk("\n");
0403 }
0404
0405 static void fas216_done(FAS216_Info *info, unsigned int result);
0406
0407
0408
0409
0410
0411
0412
0413
0414 static inline unsigned short
0415 fas216_get_last_msg(FAS216_Info *info, int pos)
0416 {
0417 unsigned short packed_msg = NOP;
0418 struct message *msg;
0419 int msgnr = 0;
0420
0421 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
0422 if (pos >= msg->fifo)
0423 break;
0424 }
0425
0426 if (msg) {
0427 if (msg->msg[0] == EXTENDED_MESSAGE)
0428 packed_msg = EXTENDED_MESSAGE | msg->msg[2] << 8;
0429 else
0430 packed_msg = msg->msg[0];
0431 }
0432
0433 fas216_log(info, LOG_MESSAGES,
0434 "Message: %04x found at position %02x\n", packed_msg, pos);
0435
0436 return packed_msg;
0437 }
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447 static int fas216_syncperiod(FAS216_Info *info, int ns)
0448 {
0449 int value = (info->ifcfg.clockrate * ns) / 1000;
0450
0451 fas216_checkmagic(info);
0452
0453 if (value < 4)
0454 value = 4;
0455 else if (value > 35)
0456 value = 35;
0457
0458 return value & 31;
0459 }
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471 static void fas216_set_sync(FAS216_Info *info, int target)
0472 {
0473 unsigned int cntl3;
0474
0475 fas216_writeb(info, REG_SOF, info->device[target].sof);
0476 fas216_writeb(info, REG_STP, info->device[target].stp);
0477
0478 cntl3 = info->scsi.cfg[2];
0479 if (info->device[target].period >= (200 / 4))
0480 cntl3 = cntl3 & ~CNTL3_FASTSCSI;
0481
0482 fas216_writeb(info, REG_CNTL3, cntl3);
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516 static void fas216_handlesync(FAS216_Info *info, char *msg)
0517 {
0518 struct fas216_device *dev = &info->device[info->SCpnt->device->id];
0519 enum { sync, async, none, reject } res = none;
0520
0521 #ifdef SCSI2_SYNC
0522 switch (msg[0]) {
0523 case MESSAGE_REJECT:
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534 if (dev->sync_state == neg_inprogress) {
0535 dev->sync_state = neg_invalid;
0536 res = async;
0537 }
0538 break;
0539
0540 case EXTENDED_MESSAGE:
0541 switch (dev->sync_state) {
0542
0543
0544
0545
0546 case neg_invalid:
0547 res = reject;
0548 break;
0549
0550
0551
0552
0553
0554
0555
0556 default:
0557 fas216_cmd(info, CMD_SETATN);
0558 if (msg[4] > info->ifcfg.sync_max_depth)
0559 msg[4] = info->ifcfg.sync_max_depth;
0560 if (msg[3] < 1000 / info->ifcfg.clockrate)
0561 msg[3] = 1000 / info->ifcfg.clockrate;
0562
0563 msgqueue_flush(&info->scsi.msgs);
0564 msgqueue_addmsg(&info->scsi.msgs, 5,
0565 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
0566 msg[3], msg[4]);
0567 info->scsi.phase = PHASE_MSGOUT_EXPECT;
0568
0569
0570
0571
0572 dev->sync_state = neg_targcomplete;
0573 res = sync;
0574 break;
0575
0576
0577
0578
0579
0580
0581
0582 case neg_inprogress:
0583 res = reject;
0584 if (msg[4] <= info->ifcfg.sync_max_depth &&
0585 msg[3] >= 1000 / info->ifcfg.clockrate) {
0586 dev->sync_state = neg_complete;
0587 res = sync;
0588 }
0589 break;
0590 }
0591 }
0592 #else
0593 res = reject;
0594 #endif
0595
0596 switch (res) {
0597 case sync:
0598 dev->period = msg[3];
0599 dev->sof = msg[4];
0600 dev->stp = fas216_syncperiod(info, msg[3] * 4);
0601 fas216_set_sync(info, info->SCpnt->device->id);
0602 break;
0603
0604 case reject:
0605 fas216_cmd(info, CMD_SETATN);
0606 msgqueue_flush(&info->scsi.msgs);
0607 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
0608 info->scsi.phase = PHASE_MSGOUT_EXPECT;
0609 fallthrough;
0610
0611 case async:
0612 dev->period = info->ifcfg.asyncperiod / 4;
0613 dev->sof = 0;
0614 dev->stp = info->scsi.async_stp;
0615 fas216_set_sync(info, info->SCpnt->device->id);
0616 break;
0617
0618 case none:
0619 break;
0620 }
0621 }
0622
0623
0624
0625
0626
0627
0628
0629
0630 static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
0631 {
0632 struct scsi_pointer *SCp = &info->scsi.SCp;
0633
0634 fas216_checkmagic(info);
0635
0636 BUG_ON(bytes_transferred < 0);
0637
0638 SCp->phase -= bytes_transferred;
0639
0640 while (bytes_transferred != 0) {
0641 if (SCp->this_residual > bytes_transferred)
0642 break;
0643
0644
0645
0646
0647 bytes_transferred -= SCp->this_residual;
0648 if (!next_SCp(SCp) && bytes_transferred) {
0649 printk(KERN_WARNING "scsi%d.%c: out of buffers\n",
0650 info->host->host_no, '0' + info->SCpnt->device->id);
0651 return;
0652 }
0653 }
0654
0655 SCp->this_residual -= bytes_transferred;
0656 if (SCp->this_residual)
0657 SCp->ptr += bytes_transferred;
0658 else
0659 SCp->ptr = NULL;
0660 }
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670 static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
0671 {
0672 struct scsi_pointer *SCp = &info->scsi.SCp;
0673
0674 fas216_checkmagic(info);
0675
0676 if (direction == DMA_OUT)
0677 fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp));
0678 else
0679 put_next_SCp_byte(SCp, fas216_readb(info, REG_FF));
0680
0681 if (SCp->this_residual == 0)
0682 next_SCp(SCp);
0683 }
0684
0685 static void fas216_set_stc(FAS216_Info *info, unsigned int length)
0686 {
0687 fas216_writeb(info, REG_STCL, length);
0688 fas216_writeb(info, REG_STCM, length >> 8);
0689 fas216_writeb(info, REG_STCH, length >> 16);
0690 }
0691
0692 static unsigned int fas216_get_ctc(FAS216_Info *info)
0693 {
0694 return fas216_readb(info, REG_CTCL) +
0695 (fas216_readb(info, REG_CTCM) << 8) +
0696 (fas216_readb(info, REG_CTCH) << 16);
0697 }
0698
0699
0700
0701
0702
0703
0704
0705
0706 static void fas216_cleanuptransfer(FAS216_Info *info)
0707 {
0708 unsigned long total, residual, fifo;
0709 fasdmatype_t dmatype = info->dma.transfer_type;
0710
0711 info->dma.transfer_type = fasdma_none;
0712
0713
0714
0715
0716 if (dmatype == fasdma_pio || dmatype == fasdma_none)
0717 return;
0718
0719 if (dmatype == fasdma_real_all)
0720 total = info->scsi.SCp.phase;
0721 else
0722 total = info->scsi.SCp.this_residual;
0723
0724 residual = fas216_get_ctc(info);
0725
0726 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
0727
0728 fas216_log(info, LOG_BUFFER, "cleaning up from previous "
0729 "transfer: length 0x%06x, residual 0x%x, fifo %d",
0730 total, residual, fifo);
0731
0732
0733
0734
0735
0736
0737
0738 if (info->scsi.phase == PHASE_DATAOUT)
0739 residual += fifo;
0740
0741 fas216_updateptrs(info, total - residual);
0742 }
0743
0744
0745
0746
0747
0748
0749
0750 static void fas216_transfer(FAS216_Info *info)
0751 {
0752 fasdmadir_t direction;
0753 fasdmatype_t dmatype;
0754
0755 fas216_log(info, LOG_BUFFER,
0756 "starttransfer: buffer %p length 0x%06x reqlen 0x%06x",
0757 info->scsi.SCp.ptr, info->scsi.SCp.this_residual,
0758 info->scsi.SCp.phase);
0759
0760 if (!info->scsi.SCp.ptr) {
0761 fas216_log(info, LOG_ERROR, "null buffer passed to "
0762 "fas216_starttransfer");
0763 print_SCp(&info->scsi.SCp, "SCp: ", "\n");
0764 print_SCp(arm_scsi_pointer(info->SCpnt), "Cmnd SCp: ", "\n");
0765 return;
0766 }
0767
0768
0769
0770
0771
0772
0773 if (info->device[info->SCpnt->device->id].sof)
0774 dmatype = fasdma_real_all;
0775 else
0776 dmatype = fasdma_pio;
0777
0778 if (info->scsi.phase == PHASE_DATAOUT)
0779 direction = DMA_OUT;
0780 else
0781 direction = DMA_IN;
0782
0783 if (info->dma.setup)
0784 dmatype = info->dma.setup(info->host, &info->scsi.SCp,
0785 direction, dmatype);
0786 info->dma.transfer_type = dmatype;
0787
0788 if (dmatype == fasdma_real_all)
0789 fas216_set_stc(info, info->scsi.SCp.phase);
0790 else
0791 fas216_set_stc(info, info->scsi.SCp.this_residual);
0792
0793 switch (dmatype) {
0794 case fasdma_pio:
0795 fas216_log(info, LOG_BUFFER, "PIO transfer");
0796 fas216_writeb(info, REG_SOF, 0);
0797 fas216_writeb(info, REG_STP, info->scsi.async_stp);
0798 fas216_cmd(info, CMD_TRANSFERINFO);
0799 fas216_pio(info, direction);
0800 break;
0801
0802 case fasdma_pseudo:
0803 fas216_log(info, LOG_BUFFER, "pseudo transfer");
0804 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
0805 info->dma.pseudo(info->host, &info->scsi.SCp,
0806 direction, info->SCpnt->transfersize);
0807 break;
0808
0809 case fasdma_real_block:
0810 fas216_log(info, LOG_BUFFER, "block dma transfer");
0811 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
0812 break;
0813
0814 case fasdma_real_all:
0815 fas216_log(info, LOG_BUFFER, "total dma transfer");
0816 fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA);
0817 break;
0818
0819 default:
0820 fas216_log(info, LOG_BUFFER | LOG_ERROR,
0821 "invalid FAS216 DMA type");
0822 break;
0823 }
0824 }
0825
0826
0827
0828
0829
0830
0831
0832 static void fas216_stoptransfer(FAS216_Info *info)
0833 {
0834 fas216_checkmagic(info);
0835
0836 if (info->dma.transfer_type == fasdma_real_all ||
0837 info->dma.transfer_type == fasdma_real_block)
0838 info->dma.stop(info->host, &info->scsi.SCp);
0839
0840 fas216_cleanuptransfer(info);
0841
0842 if (info->scsi.phase == PHASE_DATAIN) {
0843 unsigned int fifo;
0844
0845
0846
0847
0848
0849
0850 fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
0851 while (fifo && info->scsi.SCp.ptr) {
0852 *info->scsi.SCp.ptr = fas216_readb(info, REG_FF);
0853 fas216_updateptrs(info, 1);
0854 fifo--;
0855 }
0856 } else {
0857
0858
0859
0860
0861 fas216_cmd(info, CMD_FLUSHFIFO);
0862 }
0863 }
0864
0865 static void fas216_aborttransfer(FAS216_Info *info)
0866 {
0867 fas216_checkmagic(info);
0868
0869 if (info->dma.transfer_type == fasdma_real_all ||
0870 info->dma.transfer_type == fasdma_real_block)
0871 info->dma.stop(info->host, &info->scsi.SCp);
0872
0873 info->dma.transfer_type = fasdma_none;
0874 fas216_cmd(info, CMD_FLUSHFIFO);
0875 }
0876
0877 static void fas216_kick(FAS216_Info *info);
0878
0879
0880
0881
0882
0883
0884
0885 static void fas216_disconnect_intr(FAS216_Info *info)
0886 {
0887 unsigned long flags;
0888
0889 fas216_checkmagic(info);
0890
0891 fas216_log(info, LOG_CONNECT, "disconnect phase=%02x",
0892 info->scsi.phase);
0893
0894 msgqueue_flush(&info->scsi.msgs);
0895
0896 switch (info->scsi.phase) {
0897 case PHASE_SELECTION:
0898 case PHASE_SELSTEPS:
0899 fas216_done(info, DID_NO_CONNECT);
0900 break;
0901
0902 case PHASE_MSGIN_DISCONNECT:
0903 info->scsi.disconnectable = 1;
0904 info->scsi.phase = PHASE_IDLE;
0905 info->stats.disconnects += 1;
0906 spin_lock_irqsave(&info->host_lock, flags);
0907 if (info->scsi.phase == PHASE_IDLE)
0908 fas216_kick(info);
0909 spin_unlock_irqrestore(&info->host_lock, flags);
0910 break;
0911
0912 case PHASE_DONE:
0913 fas216_done(info, DID_OK);
0914 break;
0915
0916 case PHASE_MSGOUT:
0917 if (fas216_get_last_msg(info, info->scsi.msgin_fifo) == ABORT) {
0918 info->scsi.aborting = 0;
0919 fas216_done(info, DID_ABORT);
0920 break;
0921 }
0922 fallthrough;
0923
0924 default:
0925 printk(KERN_ERR "scsi%d.%c: unexpected disconnect in phase %s\n",
0926 info->host->host_no, fas216_target(info), fas216_drv_phase(info));
0927 print_debug_list();
0928 fas216_stoptransfer(info);
0929 fas216_done(info, DID_ERROR);
0930 break;
0931 }
0932 }
0933
0934
0935
0936
0937
0938
0939
0940 static void
0941 fas216_reselected_intr(FAS216_Info *info)
0942 {
0943 unsigned int cfis, i;
0944 unsigned char msg[4];
0945 unsigned char target, lun, tag;
0946
0947 fas216_checkmagic(info);
0948
0949 WARN_ON(info->scsi.phase == PHASE_SELECTION ||
0950 info->scsi.phase == PHASE_SELSTEPS);
0951
0952 cfis = fas216_readb(info, REG_CFIS);
0953
0954 fas216_log(info, LOG_CONNECT, "reconnect phase=%02x cfis=%02x",
0955 info->scsi.phase, cfis);
0956
0957 cfis &= CFIS_CF;
0958
0959 if (cfis < 2 || cfis > 4) {
0960 printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n",
0961 info->host->host_no);
0962 goto bad_message;
0963 }
0964
0965 for (i = 0; i < cfis; i++)
0966 msg[i] = fas216_readb(info, REG_FF);
0967
0968 if (!(msg[0] & (1 << info->host->this_id)) ||
0969 !(msg[1] & 0x80))
0970 goto initiator_error;
0971
0972 target = msg[0] & ~(1 << info->host->this_id);
0973 target = ffs(target) - 1;
0974 lun = msg[1] & 7;
0975 tag = 0;
0976
0977 if (cfis >= 3) {
0978 if (msg[2] != SIMPLE_QUEUE_TAG)
0979 goto initiator_error;
0980
0981 tag = msg[3];
0982 }
0983
0984
0985 fas216_writeb(info, REG_SDID, target);
0986 fas216_set_sync(info, target);
0987 msgqueue_flush(&info->scsi.msgs);
0988
0989 fas216_log(info, LOG_CONNECT, "Reconnected: target %1x lun %1x tag %02x",
0990 target, lun, tag);
0991
0992 if (info->scsi.disconnectable && info->SCpnt) {
0993 info->scsi.disconnectable = 0;
0994 if (info->SCpnt->device->id == target &&
0995 info->SCpnt->device->lun == lun &&
0996 scsi_cmd_to_rq(info->SCpnt)->tag == tag) {
0997 fas216_log(info, LOG_CONNECT, "reconnected previously executing command");
0998 } else {
0999 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1000 fas216_log(info, LOG_CONNECT, "had to move command to disconnected queue");
1001 info->SCpnt = NULL;
1002 }
1003 }
1004 if (!info->SCpnt) {
1005 info->SCpnt = queue_remove_tgtluntag(&info->queues.disconnected,
1006 target, lun, tag);
1007 fas216_log(info, LOG_CONNECT, "had to get command");
1008 }
1009
1010 if (info->SCpnt) {
1011
1012
1013
1014 info->scsi.SCp = *arm_scsi_pointer(info->SCpnt);
1015
1016 fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
1017 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1018 info->scsi.phase = PHASE_MSGIN;
1019 } else {
1020
1021
1022
1023
1024
1025
1026 fas216_cmd(info, CMD_SETATN);
1027
1028 #if 0
1029 if (tag)
1030 msgqueue_addmsg(&info->scsi.msgs, 2, ABORT_TAG, tag);
1031 else
1032 #endif
1033 msgqueue_addmsg(&info->scsi.msgs, 1, ABORT);
1034 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1035 info->scsi.aborting = 1;
1036 }
1037
1038 fas216_cmd(info, CMD_MSGACCEPTED);
1039 return;
1040
1041 initiator_error:
1042 printk(KERN_ERR "scsi%d.H: error during reselection: bytes",
1043 info->host->host_no);
1044 for (i = 0; i < cfis; i++)
1045 printk(" %02x", msg[i]);
1046 printk("\n");
1047 bad_message:
1048 fas216_cmd(info, CMD_SETATN);
1049 msgqueue_flush(&info->scsi.msgs);
1050 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1051 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1052 fas216_cmd(info, CMD_MSGACCEPTED);
1053 }
1054
1055 static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
1056 {
1057 struct scsi_pointer *scsi_pointer;
1058 int i;
1059
1060 switch (message[0]) {
1061 case COMMAND_COMPLETE:
1062 if (msglen != 1)
1063 goto unrecognised;
1064
1065 printk(KERN_ERR "scsi%d.%c: command complete with no "
1066 "status in MESSAGE_IN?\n",
1067 info->host->host_no, fas216_target(info));
1068 break;
1069
1070 case SAVE_POINTERS:
1071 if (msglen != 1)
1072 goto unrecognised;
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 scsi_pointer = arm_scsi_pointer(info->SCpnt);
1083 *scsi_pointer = info->scsi.SCp;
1084 scsi_pointer->sent_command = 0;
1085 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1086 "save data pointers: [%p, %X]",
1087 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1088 break;
1089
1090 case RESTORE_POINTERS:
1091 if (msglen != 1)
1092 goto unrecognised;
1093
1094
1095
1096
1097 info->scsi.SCp = *arm_scsi_pointer(info->SCpnt);
1098 fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
1099 "restore data pointers: [%p, 0x%x]",
1100 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1101 break;
1102
1103 case DISCONNECT:
1104 if (msglen != 1)
1105 goto unrecognised;
1106
1107 info->scsi.phase = PHASE_MSGIN_DISCONNECT;
1108 break;
1109
1110 case MESSAGE_REJECT:
1111 if (msglen != 1)
1112 goto unrecognised;
1113
1114 switch (fas216_get_last_msg(info, info->scsi.msgin_fifo)) {
1115 case EXTENDED_MESSAGE | EXTENDED_SDTR << 8:
1116 fas216_handlesync(info, message);
1117 break;
1118
1119 default:
1120 fas216_log(info, 0, "reject, last message 0x%04x",
1121 fas216_get_last_msg(info, info->scsi.msgin_fifo));
1122 }
1123 break;
1124
1125 case NOP:
1126 break;
1127
1128 case EXTENDED_MESSAGE:
1129 if (msglen < 3)
1130 goto unrecognised;
1131
1132 switch (message[2]) {
1133 case EXTENDED_SDTR:
1134 fas216_handlesync(info, message);
1135 break;
1136
1137 default:
1138 goto unrecognised;
1139 }
1140 break;
1141
1142 default:
1143 goto unrecognised;
1144 }
1145 return;
1146
1147 unrecognised:
1148 fas216_log(info, 0, "unrecognised message, rejecting");
1149 printk("scsi%d.%c: message was", info->host->host_no, fas216_target(info));
1150 for (i = 0; i < msglen; i++)
1151 printk("%s%02X", i & 31 ? " " : "\n ", message[i]);
1152 printk("\n");
1153
1154
1155
1156
1157
1158
1159 fas216_cmd(info, CMD_NOP);
1160 fas216_dumpstate(info);
1161 fas216_cmd(info, CMD_SETATN);
1162 msgqueue_flush(&info->scsi.msgs);
1163 msgqueue_addmsg(&info->scsi.msgs, 1, MESSAGE_REJECT);
1164 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1165 fas216_dumpstate(info);
1166 }
1167
1168 static int fas216_wait_cmd(FAS216_Info *info, int cmd)
1169 {
1170 int tout;
1171 int stat;
1172
1173 fas216_cmd(info, cmd);
1174
1175 for (tout = 1000; tout; tout -= 1) {
1176 stat = fas216_readb(info, REG_STAT);
1177 if (stat & (STAT_INT|STAT_PARITYERROR))
1178 break;
1179 udelay(1);
1180 }
1181
1182 return stat;
1183 }
1184
1185 static int fas216_get_msg_byte(FAS216_Info *info)
1186 {
1187 unsigned int stat = fas216_wait_cmd(info, CMD_MSGACCEPTED);
1188
1189 if ((stat & STAT_INT) == 0)
1190 goto timedout;
1191
1192 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1193 goto unexpected_phase_change;
1194
1195 fas216_readb(info, REG_INST);
1196
1197 stat = fas216_wait_cmd(info, CMD_TRANSFERINFO);
1198
1199 if ((stat & STAT_INT) == 0)
1200 goto timedout;
1201
1202 if (stat & STAT_PARITYERROR)
1203 goto parity_error;
1204
1205 if ((stat & STAT_BUSMASK) != STAT_MESGIN)
1206 goto unexpected_phase_change;
1207
1208 fas216_readb(info, REG_INST);
1209
1210 return fas216_readb(info, REG_FF);
1211
1212 timedout:
1213 fas216_log(info, LOG_ERROR, "timed out waiting for message byte");
1214 return -1;
1215
1216 unexpected_phase_change:
1217 fas216_log(info, LOG_ERROR, "unexpected phase change: status = %02x", stat);
1218 return -2;
1219
1220 parity_error:
1221 fas216_log(info, LOG_ERROR, "parity error during message in phase");
1222 return -3;
1223 }
1224
1225
1226
1227
1228
1229
1230
1231 static void fas216_message(FAS216_Info *info)
1232 {
1233 unsigned char *message = info->scsi.message;
1234 unsigned int msglen = 1;
1235 int msgbyte = 0;
1236
1237 fas216_checkmagic(info);
1238
1239 message[0] = fas216_readb(info, REG_FF);
1240
1241 if (message[0] == EXTENDED_MESSAGE) {
1242 msgbyte = fas216_get_msg_byte(info);
1243
1244 if (msgbyte >= 0) {
1245 message[1] = msgbyte;
1246
1247 for (msglen = 2; msglen < message[1] + 2; msglen++) {
1248 msgbyte = fas216_get_msg_byte(info);
1249
1250 if (msgbyte >= 0)
1251 message[msglen] = msgbyte;
1252 else
1253 break;
1254 }
1255 }
1256 }
1257
1258 if (msgbyte == -3)
1259 goto parity_error;
1260
1261 #ifdef DEBUG_MESSAGES
1262 {
1263 int i;
1264
1265 printk("scsi%d.%c: message in: ",
1266 info->host->host_no, fas216_target(info));
1267 for (i = 0; i < msglen; i++)
1268 printk("%02X ", message[i]);
1269 printk("\n");
1270 }
1271 #endif
1272
1273 fas216_parse_message(info, message, msglen);
1274 fas216_cmd(info, CMD_MSGACCEPTED);
1275 return;
1276
1277 parity_error:
1278 fas216_cmd(info, CMD_SETATN);
1279 msgqueue_flush(&info->scsi.msgs);
1280 msgqueue_addmsg(&info->scsi.msgs, 1, MSG_PARITY_ERROR);
1281 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1282 fas216_cmd(info, CMD_MSGACCEPTED);
1283 return;
1284 }
1285
1286
1287
1288
1289
1290
1291
1292 static void fas216_send_command(FAS216_Info *info)
1293 {
1294 int i;
1295
1296 fas216_checkmagic(info);
1297
1298 fas216_cmd(info, CMD_NOP|CMD_WITHDMA);
1299 fas216_cmd(info, CMD_FLUSHFIFO);
1300
1301
1302 for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++)
1303 fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]);
1304
1305 fas216_cmd(info, CMD_TRANSFERINFO);
1306
1307 info->scsi.phase = PHASE_COMMAND;
1308 }
1309
1310
1311
1312
1313
1314
1315
1316
1317 static void fas216_send_messageout(FAS216_Info *info, int start)
1318 {
1319 unsigned int tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1320
1321 fas216_checkmagic(info);
1322
1323 fas216_cmd(info, CMD_FLUSHFIFO);
1324
1325 if (tot_msglen) {
1326 struct message *msg;
1327 int msgnr = 0;
1328
1329 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1330 int i;
1331
1332 for (i = start; i < msg->length; i++)
1333 fas216_writeb(info, REG_FF, msg->msg[i]);
1334
1335 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1336 start = 0;
1337 }
1338 } else
1339 fas216_writeb(info, REG_FF, NOP);
1340
1341 fas216_cmd(info, CMD_TRANSFERINFO);
1342
1343 info->scsi.phase = PHASE_MSGOUT;
1344 }
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354 static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1355 {
1356 fas216_checkmagic(info);
1357
1358 fas216_log(info, LOG_BUSSERVICE,
1359 "bus service: stat=%02x is=%02x phase=%02x",
1360 stat, is, info->scsi.phase);
1361
1362 switch (info->scsi.phase) {
1363 case PHASE_SELECTION:
1364 if ((is & IS_BITS) != IS_MSGBYTESENT)
1365 goto bad_is;
1366 break;
1367
1368 case PHASE_SELSTEPS:
1369 switch (is & IS_BITS) {
1370 case IS_SELARB:
1371 case IS_MSGBYTESENT:
1372 goto bad_is;
1373
1374 case IS_NOTCOMMAND:
1375 case IS_EARLYPHASE:
1376 if ((stat & STAT_BUSMASK) == STAT_MESGIN)
1377 break;
1378 goto bad_is;
1379
1380 case IS_COMPLETE:
1381 break;
1382 }
1383 break;
1384
1385 default:
1386 break;
1387 }
1388
1389 fas216_cmd(info, CMD_NOP);
1390
1391 #define STATE(st,ph) ((ph) << 3 | (st))
1392
1393
1394
1395 switch (STATE(stat & STAT_BUSMASK, info->scsi.phase)) {
1396 case STATE(STAT_DATAIN, PHASE_SELSTEPS):
1397 case STATE(STAT_DATAIN, PHASE_MSGOUT):
1398 case STATE(STAT_DATAIN, PHASE_COMMAND):
1399 case STATE(STAT_DATAIN, PHASE_MSGIN):
1400 info->scsi.phase = PHASE_DATAIN;
1401 fas216_transfer(info);
1402 return;
1403
1404 case STATE(STAT_DATAIN, PHASE_DATAIN):
1405 case STATE(STAT_DATAOUT, PHASE_DATAOUT):
1406 fas216_cleanuptransfer(info);
1407 fas216_transfer(info);
1408 return;
1409
1410 case STATE(STAT_DATAOUT, PHASE_SELSTEPS):
1411 case STATE(STAT_DATAOUT, PHASE_MSGOUT):
1412 case STATE(STAT_DATAOUT, PHASE_COMMAND):
1413 case STATE(STAT_DATAOUT, PHASE_MSGIN):
1414 fas216_cmd(info, CMD_FLUSHFIFO);
1415 info->scsi.phase = PHASE_DATAOUT;
1416 fas216_transfer(info);
1417 return;
1418
1419 case STATE(STAT_STATUS, PHASE_DATAOUT):
1420 case STATE(STAT_STATUS, PHASE_DATAIN):
1421 fas216_stoptransfer(info);
1422 fallthrough;
1423
1424 case STATE(STAT_STATUS, PHASE_SELSTEPS):
1425 case STATE(STAT_STATUS, PHASE_MSGOUT):
1426 case STATE(STAT_STATUS, PHASE_COMMAND):
1427 case STATE(STAT_STATUS, PHASE_MSGIN):
1428 fas216_cmd(info, CMD_INITCMDCOMPLETE);
1429 info->scsi.phase = PHASE_STATUS;
1430 return;
1431
1432 case STATE(STAT_MESGIN, PHASE_DATAOUT):
1433 case STATE(STAT_MESGIN, PHASE_DATAIN):
1434 fas216_stoptransfer(info);
1435 fallthrough;
1436
1437 case STATE(STAT_MESGIN, PHASE_COMMAND):
1438 case STATE(STAT_MESGIN, PHASE_SELSTEPS):
1439 case STATE(STAT_MESGIN, PHASE_MSGOUT):
1440 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1441 fas216_cmd(info, CMD_FLUSHFIFO);
1442 fas216_cmd(info, CMD_TRANSFERINFO);
1443 info->scsi.phase = PHASE_MSGIN;
1444 return;
1445
1446 case STATE(STAT_MESGIN, PHASE_MSGIN):
1447 info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF;
1448 fas216_cmd(info, CMD_TRANSFERINFO);
1449 return;
1450
1451 case STATE(STAT_COMMAND, PHASE_MSGOUT):
1452 case STATE(STAT_COMMAND, PHASE_MSGIN):
1453 fas216_send_command(info);
1454 info->scsi.phase = PHASE_COMMAND;
1455 return;
1456
1457
1458
1459
1460
1461 case STATE(STAT_MESGOUT, PHASE_SELECTION):
1462 fas216_send_messageout(info, 1);
1463 return;
1464
1465
1466
1467
1468 case STATE(STAT_MESGOUT, PHASE_SELSTEPS):
1469 case STATE(STAT_MESGOUT, PHASE_MSGOUT):
1470
1471
1472
1473
1474
1475
1476 if (info->device[info->SCpnt->device->id].parity_check) {
1477
1478
1479
1480
1481 info->device[info->SCpnt->device->id].parity_check = 0;
1482 info->device[info->SCpnt->device->id].parity_enabled = 1;
1483 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1484 }
1485
1486 if (msgqueue_msglength(&info->scsi.msgs) > 1)
1487 fas216_cmd(info, CMD_SETATN);
1488 fallthrough;
1489
1490
1491
1492
1493 case STATE(STAT_MESGOUT, PHASE_MSGOUT_EXPECT):
1494 fas216_send_messageout(info, 0);
1495 return;
1496
1497
1498
1499
1500
1501 case STATE(STAT_COMMAND, PHASE_COMMAND):
1502
1503
1504
1505
1506
1507
1508 printk(KERN_ERR "scsi%d.%c: "
1509 "target trying to receive more command bytes\n",
1510 info->host->host_no, fas216_target(info));
1511 fas216_cmd(info, CMD_SETATN);
1512 fas216_set_stc(info, 15);
1513 fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA);
1514 msgqueue_flush(&info->scsi.msgs);
1515 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1516 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1517 return;
1518 }
1519
1520 if (info->scsi.phase == PHASE_MSGIN_DISCONNECT) {
1521 printk(KERN_ERR "scsi%d.%c: disconnect message received, but bus service %s?\n",
1522 info->host->host_no, fas216_target(info),
1523 fas216_bus_phase(stat));
1524 msgqueue_flush(&info->scsi.msgs);
1525 fas216_cmd(info, CMD_SETATN);
1526 msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR);
1527 info->scsi.phase = PHASE_MSGOUT_EXPECT;
1528 info->scsi.aborting = 1;
1529 fas216_cmd(info, CMD_TRANSFERINFO);
1530 return;
1531 }
1532 printk(KERN_ERR "scsi%d.%c: bus phase %s after %s?\n",
1533 info->host->host_no, fas216_target(info),
1534 fas216_bus_phase(stat),
1535 fas216_drv_phase(info));
1536 print_debug_list();
1537 return;
1538
1539 bad_is:
1540 fas216_log(info, 0, "bus service at step %d?", is & IS_BITS);
1541 fas216_dumpstate(info);
1542 print_debug_list();
1543
1544 fas216_done(info, DID_ERROR);
1545 }
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555 static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int is)
1556 {
1557 unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF;
1558
1559 fas216_checkmagic(info);
1560
1561 fas216_log(info, LOG_FUNCTIONDONE,
1562 "function done: stat=%02x is=%02x phase=%02x",
1563 stat, is, info->scsi.phase);
1564
1565 switch (info->scsi.phase) {
1566 case PHASE_STATUS:
1567 if (fifo_len != 2) {
1568 fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len);
1569 }
1570
1571
1572
1573 info->scsi.SCp.Status = fas216_readb(info, REG_FF);
1574 info->scsi.SCp.Message = fas216_readb(info, REG_FF);
1575 info->scsi.phase = PHASE_DONE;
1576 fas216_cmd(info, CMD_MSGACCEPTED);
1577 break;
1578
1579 case PHASE_IDLE:
1580 case PHASE_SELECTION:
1581 case PHASE_SELSTEPS:
1582 break;
1583
1584 case PHASE_MSGIN:
1585 if ((stat & STAT_BUSMASK) == STAT_MESGIN) {
1586 info->scsi.msgin_fifo = fifo_len;
1587 fas216_message(info);
1588 break;
1589 }
1590 fallthrough;
1591
1592 default:
1593 fas216_log(info, 0, "internal phase %s for function done?"
1594 " What do I do with this?",
1595 fas216_target(info), fas216_drv_phase(info));
1596 }
1597 }
1598
1599 static void fas216_bus_reset(FAS216_Info *info)
1600 {
1601 neg_t sync_state;
1602 int i;
1603
1604 msgqueue_flush(&info->scsi.msgs);
1605
1606 sync_state = neg_invalid;
1607
1608 #ifdef SCSI2_SYNC
1609 if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA))
1610 sync_state = neg_wait;
1611 #endif
1612
1613 info->scsi.phase = PHASE_IDLE;
1614 info->SCpnt = NULL;
1615 memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp));
1616
1617 for (i = 0; i < 8; i++) {
1618 info->device[i].disconnect_ok = info->ifcfg.disconnect_ok;
1619 info->device[i].sync_state = sync_state;
1620 info->device[i].period = info->ifcfg.asyncperiod / 4;
1621 info->device[i].stp = info->scsi.async_stp;
1622 info->device[i].sof = 0;
1623 info->device[i].wide_xfer = 0;
1624 }
1625
1626 info->rst_bus_status = 1;
1627 wake_up(&info->eh_wait);
1628 }
1629
1630
1631
1632
1633
1634
1635
1636 irqreturn_t fas216_intr(FAS216_Info *info)
1637 {
1638 unsigned char inst, is, stat;
1639 int handled = IRQ_NONE;
1640
1641 fas216_checkmagic(info);
1642
1643 stat = fas216_readb(info, REG_STAT);
1644 is = fas216_readb(info, REG_IS);
1645 inst = fas216_readb(info, REG_INST);
1646
1647 add_debug_list(stat, is, inst, info->scsi.phase);
1648
1649 if (stat & STAT_INT) {
1650 if (inst & INST_BUSRESET) {
1651 fas216_log(info, 0, "bus reset detected");
1652 fas216_bus_reset(info);
1653 scsi_report_bus_reset(info->host, 0);
1654 } else if (inst & INST_ILLEGALCMD) {
1655 fas216_log(info, LOG_ERROR, "illegal command given\n");
1656 fas216_dumpstate(info);
1657 print_debug_list();
1658 } else if (inst & INST_DISCONNECT)
1659 fas216_disconnect_intr(info);
1660 else if (inst & INST_RESELECTED)
1661 fas216_reselected_intr(info);
1662 else if (inst & INST_BUSSERVICE)
1663 fas216_busservice_intr(info, stat, is);
1664 else if (inst & INST_FUNCDONE)
1665 fas216_funcdone_intr(info, stat, is);
1666 else
1667 fas216_log(info, 0, "unknown interrupt received:"
1668 " phase %s inst %02X is %02X stat %02X",
1669 fas216_drv_phase(info), inst, is, stat);
1670 handled = IRQ_HANDLED;
1671 }
1672 return handled;
1673 }
1674
1675 static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1676 {
1677 int tot_msglen;
1678
1679
1680 fas216_set_stc(info, 0);
1681 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1682
1683
1684 fas216_cmd(info, CMD_FLUSHFIFO);
1685
1686
1687 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1688 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1689
1690
1691 fas216_set_sync(info, SCpnt->device->id);
1692
1693 tot_msglen = msgqueue_msglength(&info->scsi.msgs);
1694
1695 #ifdef DEBUG_MESSAGES
1696 {
1697 struct message *msg;
1698 int msgnr = 0, i;
1699
1700 printk("scsi%d.%c: message out: ",
1701 info->host->host_no, '0' + SCpnt->device->id);
1702 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1703 printk("{ ");
1704 for (i = 0; i < msg->length; i++)
1705 printk("%02x ", msg->msg[i]);
1706 printk("} ");
1707 }
1708 printk("\n");
1709 }
1710 #endif
1711
1712 if (tot_msglen == 1 || tot_msglen == 3) {
1713
1714
1715
1716 struct message *msg;
1717 int msgnr = 0, i;
1718
1719 info->scsi.phase = PHASE_SELSTEPS;
1720
1721
1722 while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) {
1723 for (i = 0; i < msg->length; i++)
1724 fas216_writeb(info, REG_FF, msg->msg[i]);
1725 msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF);
1726 }
1727
1728
1729 for (i = 0; i < SCpnt->cmd_len; i++)
1730 fas216_writeb(info, REG_FF, SCpnt->cmnd[i]);
1731
1732 if (tot_msglen == 1)
1733 fas216_cmd(info, CMD_SELECTATN);
1734 else
1735 fas216_cmd(info, CMD_SELECTATN3);
1736 } else {
1737
1738
1739
1740
1741
1742 struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1743
1744 fas216_writeb(info, REG_FF, msg->msg[0]);
1745 msg->fifo = 1;
1746
1747 fas216_cmd(info, CMD_SELECTATNSTOP);
1748 }
1749 }
1750
1751
1752
1753
1754
1755
1756 static int parity_test(FAS216_Info *info, int target)
1757 {
1758 #if 0
1759 if (target == 3) {
1760 info->device[target].parity_check = 0;
1761 return 1;
1762 }
1763 #endif
1764 return info->device[target].parity_check;
1765 }
1766
1767 static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1768 {
1769 int disconnect_ok;
1770
1771
1772
1773
1774 info->scsi.phase = PHASE_SELECTION;
1775 info->scsi.SCp = *arm_scsi_pointer(SCpnt);
1776 info->SCpnt = SCpnt;
1777 info->dma.transfer_type = fasdma_none;
1778
1779 if (parity_test(info, SCpnt->device->id))
1780 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE);
1781 else
1782 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
1783
1784
1785
1786
1787 disconnect_ok = SCpnt->cmnd[0] != REQUEST_SENSE &&
1788 info->device[SCpnt->device->id].disconnect_ok;
1789
1790
1791
1792
1793 msgqueue_flush(&info->scsi.msgs);
1794 msgqueue_addmsg(&info->scsi.msgs, 1, IDENTIFY(disconnect_ok, SCpnt->device->lun));
1795
1796
1797
1798
1799 if (SCpnt->device->simple_tags)
1800 msgqueue_addmsg(&info->scsi.msgs, 2, SIMPLE_QUEUE_TAG,
1801 scsi_cmd_to_rq(SCpnt)->tag);
1802
1803 do {
1804 #ifdef SCSI2_SYNC
1805 if ((info->device[SCpnt->device->id].sync_state == neg_wait ||
1806 info->device[SCpnt->device->id].sync_state == neg_complete) &&
1807 (SCpnt->cmnd[0] == REQUEST_SENSE ||
1808 SCpnt->cmnd[0] == INQUIRY)) {
1809 info->device[SCpnt->device->id].sync_state = neg_inprogress;
1810 msgqueue_addmsg(&info->scsi.msgs, 5,
1811 EXTENDED_MESSAGE, 3, EXTENDED_SDTR,
1812 1000 / info->ifcfg.clockrate,
1813 info->ifcfg.sync_max_depth);
1814 break;
1815 }
1816 #endif
1817 } while (0);
1818
1819 __fas216_start_command(info, SCpnt);
1820 }
1821
1822 static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
1823 {
1824 set_bit(SCpnt->device->id * 8 +
1825 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
1826
1827 info->stats.removes += 1;
1828 switch (SCpnt->cmnd[0]) {
1829 case WRITE_6:
1830 case WRITE_10:
1831 case WRITE_12:
1832 info->stats.writes += 1;
1833 break;
1834 case READ_6:
1835 case READ_10:
1836 case READ_12:
1837 info->stats.reads += 1;
1838 break;
1839 default:
1840 info->stats.miscs += 1;
1841 break;
1842 }
1843 }
1844
1845 static void fas216_do_bus_device_reset(FAS216_Info *info,
1846 struct scsi_cmnd *SCpnt)
1847 {
1848 struct message *msg;
1849
1850
1851
1852
1853 info->scsi.phase = PHASE_SELECTION;
1854 info->scsi.SCp = *arm_scsi_pointer(SCpnt);
1855 info->SCpnt = SCpnt;
1856 info->dma.transfer_type = fasdma_none;
1857
1858 fas216_log(info, LOG_ERROR, "sending bus device reset");
1859
1860 msgqueue_flush(&info->scsi.msgs);
1861 msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET);
1862
1863
1864 fas216_set_stc(info, 0);
1865 fas216_cmd(info, CMD_NOP | CMD_WITHDMA);
1866
1867
1868 fas216_cmd(info, CMD_FLUSHFIFO);
1869
1870
1871 fas216_writeb(info, REG_SDID, BUSID(SCpnt->device->id));
1872 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
1873
1874
1875 fas216_set_sync(info, SCpnt->device->id);
1876
1877 msg = msgqueue_getmsg(&info->scsi.msgs, 0);
1878
1879 fas216_writeb(info, REG_FF, BUS_DEVICE_RESET);
1880 msg->fifo = 1;
1881
1882 fas216_cmd(info, CMD_SELECTATNSTOP);
1883 }
1884
1885
1886
1887
1888
1889
1890
1891
1892 static void fas216_kick(FAS216_Info *info)
1893 {
1894 struct scsi_cmnd *SCpnt = NULL;
1895 #define TYPE_OTHER 0
1896 #define TYPE_RESET 1
1897 #define TYPE_QUEUE 2
1898 int where_from = TYPE_OTHER;
1899
1900 fas216_checkmagic(info);
1901
1902
1903
1904
1905 do {
1906 if (info->rstSCpnt) {
1907 SCpnt = info->rstSCpnt;
1908
1909 where_from = TYPE_RESET;
1910 break;
1911 }
1912
1913 if (info->reqSCpnt) {
1914 SCpnt = info->reqSCpnt;
1915 info->reqSCpnt = NULL;
1916 break;
1917 }
1918
1919 if (info->origSCpnt) {
1920 SCpnt = info->origSCpnt;
1921 info->origSCpnt = NULL;
1922 break;
1923 }
1924
1925
1926 if (!SCpnt) {
1927 SCpnt = queue_remove_exclude(&info->queues.issue,
1928 info->busyluns);
1929 where_from = TYPE_QUEUE;
1930 break;
1931 }
1932 } while (0);
1933
1934 if (!SCpnt) {
1935
1936
1937
1938 fas216_cmd(info, CMD_ENABLESEL);
1939 return;
1940 }
1941
1942
1943
1944
1945 fas216_cmd(info, CMD_DISABLESEL);
1946
1947 if (info->scsi.disconnectable && info->SCpnt) {
1948 fas216_log(info, LOG_CONNECT,
1949 "moved command for %d to disconnected queue",
1950 info->SCpnt->device->id);
1951 queue_add_cmd_tail(&info->queues.disconnected, info->SCpnt);
1952 info->scsi.disconnectable = 0;
1953 info->SCpnt = NULL;
1954 }
1955
1956 fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt,
1957 "starting");
1958
1959 switch (where_from) {
1960 case TYPE_QUEUE:
1961 fas216_allocate_tag(info, SCpnt);
1962 fallthrough;
1963 case TYPE_OTHER:
1964 fas216_start_command(info, SCpnt);
1965 break;
1966 case TYPE_RESET:
1967 fas216_do_bus_device_reset(info, SCpnt);
1968 break;
1969 }
1970
1971 fas216_log(info, LOG_CONNECT, "select: data pointers [%p, %X]",
1972 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
1973
1974
1975
1976
1977
1978 }
1979
1980
1981
1982
1983 static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
1984 unsigned int result)
1985 {
1986 fas216_log(info, LOG_ERROR, "fas216 device reset complete");
1987
1988 info->rstSCpnt = NULL;
1989 info->rst_dev_status = 1;
1990 wake_up(&info->eh_wait);
1991 }
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001 static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
2002 unsigned int result)
2003 {
2004 struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
2005
2006 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2007 "request sense complete, result=0x%04x%02x%02x",
2008 result, scsi_pointer->Message, scsi_pointer->Status);
2009
2010 if (result != DID_OK || scsi_pointer->Status != SAM_STAT_GOOD)
2011
2012
2013
2014
2015
2016 memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
2017
2018
2019
2020
2021
2022
2023
2024
2025 scsi_eh_restore_cmnd(SCpnt, &info->ses);
2026 fas216_cmd_priv(SCpnt)->scsi_done(SCpnt);
2027 }
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037 static void
2038 fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
2039 {
2040 struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
2041
2042 info->stats.fins += 1;
2043
2044 set_host_byte(SCpnt, result);
2045 if (result == DID_OK)
2046 scsi_msg_to_host_byte(SCpnt, info->scsi.SCp.Message);
2047 set_status_byte(SCpnt, info->scsi.SCp.Status);
2048
2049 fas216_log_command(info, LOG_CONNECT, SCpnt,
2050 "command complete, result=0x%08x", SCpnt->result);
2051
2052
2053
2054
2055 if (get_host_byte(SCpnt) != DID_OK)
2056 goto done;
2057
2058
2059
2060
2061
2062 if (get_status_byte(SCpnt) == SAM_STAT_CHECK_CONDITION ||
2063 get_status_byte(SCpnt) == SAM_STAT_COMMAND_TERMINATED)
2064 goto request_sense;
2065
2066
2067
2068
2069
2070 if (get_status_byte(SCpnt) != SAM_STAT_GOOD)
2071 goto done;
2072
2073
2074
2075
2076
2077
2078
2079
2080 if (info->scsi.SCp.ptr) {
2081 switch (SCpnt->cmnd[0]) {
2082 case INQUIRY:
2083 case START_STOP:
2084 case MODE_SENSE:
2085 break;
2086
2087 default:
2088 scmd_printk(KERN_ERR, SCpnt,
2089 "incomplete data transfer detected: res=%08X ptr=%p len=%X\n",
2090 SCpnt->result, info->scsi.SCp.ptr,
2091 info->scsi.SCp.this_residual);
2092 scsi_print_command(SCpnt);
2093 set_host_byte(SCpnt, DID_ERROR);
2094 goto request_sense;
2095 }
2096 }
2097
2098 done:
2099 if (fas216_cmd_priv(SCpnt)->scsi_done) {
2100 fas216_cmd_priv(SCpnt)->scsi_done(SCpnt);
2101 return;
2102 }
2103
2104 panic("scsi%d.H: null scsi_done function in fas216_done",
2105 info->host->host_no);
2106
2107
2108 request_sense:
2109 if (SCpnt->cmnd[0] == REQUEST_SENSE)
2110 goto done;
2111
2112 scsi_eh_prep_cmnd(SCpnt, &info->ses, NULL, 0, ~0);
2113 fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
2114 "requesting sense");
2115 init_SCp(SCpnt);
2116 scsi_pointer->Message = 0;
2117 scsi_pointer->Status = 0;
2118 SCpnt->host_scribble = (void *)fas216_rq_sns_done;
2119
2120
2121
2122
2123
2124
2125 if (info->reqSCpnt)
2126 printk(KERN_WARNING "scsi%d.%c: losing request command\n",
2127 info->host->host_no, '0' + SCpnt->device->id);
2128 info->reqSCpnt = SCpnt;
2129 }
2130
2131
2132
2133
2134
2135
2136
2137
2138 static void fas216_done(FAS216_Info *info, unsigned int result)
2139 {
2140 void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
2141 struct scsi_cmnd *SCpnt;
2142 unsigned long flags;
2143
2144 fas216_checkmagic(info);
2145
2146 if (!info->SCpnt)
2147 goto no_command;
2148
2149 SCpnt = info->SCpnt;
2150 info->SCpnt = NULL;
2151 info->scsi.phase = PHASE_IDLE;
2152
2153 if (info->scsi.aborting) {
2154 fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
2155 result = DID_ABORT;
2156 info->scsi.aborting = 0;
2157 }
2158
2159
2160
2161
2162
2163 if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
2164 scmd_printk(KERN_INFO, SCpnt,
2165 "zero bytes left to transfer, but buffer pointer still valid: ptr=%p len=%08x\n",
2166 info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
2167 info->scsi.SCp.ptr = NULL;
2168 scsi_print_command(SCpnt);
2169 }
2170
2171
2172
2173
2174
2175
2176 info->device[SCpnt->device->id].parity_check = 0;
2177 clear_bit(SCpnt->device->id * 8 +
2178 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2179
2180 fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
2181 fn(info, SCpnt, result);
2182
2183 if (info->scsi.irq) {
2184 spin_lock_irqsave(&info->host_lock, flags);
2185 if (info->scsi.phase == PHASE_IDLE)
2186 fas216_kick(info);
2187 spin_unlock_irqrestore(&info->host_lock, flags);
2188 }
2189 return;
2190
2191 no_command:
2192 panic("scsi%d.H: null command in fas216_done",
2193 info->host->host_no);
2194 }
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205 static int fas216_queue_command_internal(struct scsi_cmnd *SCpnt,
2206 void (*done)(struct scsi_cmnd *))
2207 {
2208 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2209 int result;
2210
2211 fas216_checkmagic(info);
2212
2213 fas216_log_command(info, LOG_CONNECT, SCpnt,
2214 "received command (%p)", SCpnt);
2215
2216 fas216_cmd_priv(SCpnt)->scsi_done = done;
2217 SCpnt->host_scribble = (void *)fas216_std_done;
2218 SCpnt->result = 0;
2219
2220 init_SCp(SCpnt);
2221
2222 info->stats.queues += 1;
2223
2224 spin_lock(&info->host_lock);
2225
2226
2227
2228
2229
2230 result = !queue_add_cmd_ordered(&info->queues.issue, SCpnt);
2231
2232
2233
2234
2235
2236 if (result == 0 && info->scsi.phase == PHASE_IDLE)
2237 fas216_kick(info);
2238 spin_unlock(&info->host_lock);
2239
2240 fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
2241 result ? "failure" : "success");
2242
2243 return result;
2244 }
2245
2246 static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt)
2247 {
2248 return fas216_queue_command_internal(SCpnt, scsi_done);
2249 }
2250
2251 DEF_SCSI_QCMD(fas216_queue_command)
2252
2253
2254
2255
2256
2257
2258
2259 static void fas216_internal_done(struct scsi_cmnd *SCpnt)
2260 {
2261 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2262
2263 fas216_checkmagic(info);
2264
2265 info->internal_done = 1;
2266 }
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276 static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt)
2277 {
2278 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2279
2280 fas216_checkmagic(info);
2281
2282
2283
2284
2285
2286 BUG_ON(info->scsi.irq);
2287
2288 info->internal_done = 0;
2289 fas216_queue_command_internal(SCpnt, fas216_internal_done);
2290
2291
2292
2293
2294
2295
2296
2297 spin_unlock_irq(info->host->host_lock);
2298
2299 while (!info->internal_done) {
2300
2301
2302
2303
2304
2305
2306
2307
2308 if (fas216_readb(info, REG_STAT) & STAT_INT) {
2309 spin_lock_irq(info->host->host_lock);
2310 fas216_intr(info);
2311 spin_unlock_irq(info->host->host_lock);
2312 }
2313 }
2314
2315 spin_lock_irq(info->host->host_lock);
2316
2317 scsi_done(SCpnt);
2318
2319 return 0;
2320 }
2321
2322 DEF_SCSI_QCMD(fas216_noqueue_command)
2323
2324
2325
2326
2327
2328 static void fas216_eh_timer(struct timer_list *t)
2329 {
2330 FAS216_Info *info = from_timer(info, t, eh_timer);
2331
2332 fas216_log(info, LOG_ERROR, "error handling timed out\n");
2333
2334 del_timer(&info->eh_timer);
2335
2336 if (info->rst_bus_status == 0)
2337 info->rst_bus_status = -1;
2338 if (info->rst_dev_status == 0)
2339 info->rst_dev_status = -1;
2340
2341 wake_up(&info->eh_wait);
2342 }
2343
2344 enum res_find {
2345 res_failed,
2346 res_success,
2347 res_hw_abort
2348 };
2349
2350
2351
2352
2353
2354
2355
2356
2357 static enum res_find fas216_find_command(FAS216_Info *info,
2358 struct scsi_cmnd *SCpnt)
2359 {
2360 enum res_find res = res_failed;
2361
2362 if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
2363
2364
2365
2366
2367
2368
2369 printk("on issue queue ");
2370
2371 res = res_success;
2372 } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
2373
2374
2375
2376
2377
2378 printk("on disconnected queue ");
2379
2380 res = res_hw_abort;
2381 } else if (info->SCpnt == SCpnt) {
2382 printk("executing ");
2383
2384 switch (info->scsi.phase) {
2385
2386
2387
2388
2389 case PHASE_IDLE:
2390 if (info->scsi.disconnectable) {
2391 info->scsi.disconnectable = 0;
2392 info->SCpnt = NULL;
2393 res = res_hw_abort;
2394 }
2395 break;
2396
2397 default:
2398 break;
2399 }
2400 } else if (info->origSCpnt == SCpnt) {
2401
2402
2403
2404
2405
2406
2407 info->origSCpnt = NULL;
2408 clear_bit(SCpnt->device->id * 8 +
2409 (u8)(SCpnt->device->lun & 0x7), info->busyluns);
2410 printk("waiting for execution ");
2411 res = res_success;
2412 } else
2413 printk("unknown ");
2414
2415 return res;
2416 }
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426 int fas216_eh_abort(struct scsi_cmnd *SCpnt)
2427 {
2428 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2429 int result = FAILED;
2430
2431 fas216_checkmagic(info);
2432
2433 info->stats.aborts += 1;
2434
2435 scmd_printk(KERN_WARNING, SCpnt, "abort command\n");
2436
2437 print_debug_list();
2438 fas216_dumpstate(info);
2439
2440 switch (fas216_find_command(info, SCpnt)) {
2441
2442
2443
2444
2445
2446 case res_success:
2447 scmd_printk(KERN_WARNING, SCpnt, "abort %p success\n", SCpnt);
2448 result = SUCCESS;
2449 break;
2450
2451
2452
2453
2454
2455
2456 case res_hw_abort:
2457
2458
2459
2460
2461 default:
2462 case res_failed:
2463 scmd_printk(KERN_WARNING, SCpnt, "abort %p failed\n", SCpnt);
2464 break;
2465 }
2466
2467 return result;
2468 }
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479 int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
2480 {
2481 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2482 unsigned long flags;
2483 int i, res = FAILED, target = SCpnt->device->id;
2484
2485 fas216_log(info, LOG_ERROR, "device reset for target %d", target);
2486
2487 spin_lock_irqsave(&info->host_lock, flags);
2488
2489 do {
2490
2491
2492
2493
2494
2495
2496 if (info->SCpnt && !info->scsi.disconnectable &&
2497 info->SCpnt->device->id == SCpnt->device->id)
2498 break;
2499
2500
2501
2502
2503
2504
2505
2506 queue_remove_all_target(&info->queues.issue, target);
2507 queue_remove_all_target(&info->queues.disconnected, target);
2508 if (info->origSCpnt && info->origSCpnt->device->id == target)
2509 info->origSCpnt = NULL;
2510 if (info->reqSCpnt && info->reqSCpnt->device->id == target)
2511 info->reqSCpnt = NULL;
2512 for (i = 0; i < 8; i++)
2513 clear_bit(target * 8 + i, info->busyluns);
2514
2515
2516
2517
2518
2519 SCpnt->host_scribble = (void *)fas216_devicereset_done;
2520
2521 info->rst_dev_status = 0;
2522 info->rstSCpnt = SCpnt;
2523
2524 if (info->scsi.phase == PHASE_IDLE)
2525 fas216_kick(info);
2526
2527 mod_timer(&info->eh_timer, jiffies + 30 * HZ);
2528 spin_unlock_irqrestore(&info->host_lock, flags);
2529
2530
2531
2532
2533 wait_event(info->eh_wait, info->rst_dev_status);
2534
2535 del_timer_sync(&info->eh_timer);
2536 spin_lock_irqsave(&info->host_lock, flags);
2537 info->rstSCpnt = NULL;
2538
2539 if (info->rst_dev_status == 1)
2540 res = SUCCESS;
2541 } while (0);
2542
2543 SCpnt->host_scribble = NULL;
2544 spin_unlock_irqrestore(&info->host_lock, flags);
2545
2546 fas216_log(info, LOG_ERROR, "device reset complete: %s\n",
2547 res == SUCCESS ? "success" : "failed");
2548
2549 return res;
2550 }
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560 int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
2561 {
2562 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2563 unsigned long flags;
2564 struct scsi_device *SDpnt;
2565
2566 fas216_checkmagic(info);
2567 fas216_log(info, LOG_ERROR, "resetting bus");
2568
2569 info->stats.bus_resets += 1;
2570
2571 spin_lock_irqsave(&info->host_lock, flags);
2572
2573
2574
2575
2576 fas216_aborttransfer(info);
2577 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2578
2579
2580
2581
2582 while (fas216_readb(info, REG_STAT) & STAT_INT)
2583 fas216_readb(info, REG_INST);
2584
2585 info->rst_bus_status = 0;
2586
2587
2588
2589
2590
2591
2592 shost_for_each_device(SDpnt, info->host) {
2593 int i;
2594
2595 if (SDpnt->soft_reset)
2596 continue;
2597
2598 queue_remove_all_target(&info->queues.issue, SDpnt->id);
2599 queue_remove_all_target(&info->queues.disconnected, SDpnt->id);
2600 if (info->origSCpnt && info->origSCpnt->device->id == SDpnt->id)
2601 info->origSCpnt = NULL;
2602 if (info->reqSCpnt && info->reqSCpnt->device->id == SDpnt->id)
2603 info->reqSCpnt = NULL;
2604 info->SCpnt = NULL;
2605
2606 for (i = 0; i < 8; i++)
2607 clear_bit(SDpnt->id * 8 + i, info->busyluns);
2608 }
2609
2610 info->scsi.phase = PHASE_IDLE;
2611
2612
2613
2614
2615
2616 fas216_cmd(info, CMD_RESETSCSI);
2617
2618 mod_timer(&info->eh_timer, jiffies + HZ);
2619 spin_unlock_irqrestore(&info->host_lock, flags);
2620
2621
2622
2623
2624 wait_event(info->eh_wait, info->rst_bus_status);
2625 del_timer_sync(&info->eh_timer);
2626
2627 fas216_log(info, LOG_ERROR, "bus reset complete: %s\n",
2628 info->rst_bus_status == 1 ? "success" : "failed");
2629
2630 return info->rst_bus_status == 1 ? SUCCESS : FAILED;
2631 }
2632
2633
2634
2635
2636
2637
2638
2639 static void fas216_init_chip(FAS216_Info *info)
2640 {
2641 unsigned int clock = ((info->ifcfg.clockrate - 1) / 5 + 1) & 7;
2642 fas216_writeb(info, REG_CLKF, clock);
2643 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2644 fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]);
2645 fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]);
2646 fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout);
2647 fas216_writeb(info, REG_SOF, 0);
2648 fas216_writeb(info, REG_STP, info->scsi.async_stp);
2649 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2650 }
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660 int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
2661 {
2662 FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
2663
2664 spin_lock_irq(info->host->host_lock);
2665
2666 fas216_checkmagic(info);
2667
2668 fas216_log(info, LOG_ERROR, "resetting host");
2669
2670
2671
2672
2673 fas216_cmd(info, CMD_RESETCHIP);
2674
2675
2676
2677
2678
2679
2680
2681 spin_unlock_irq(info->host->host_lock);
2682 msleep(50 * 1000/100);
2683 spin_lock_irq(info->host->host_lock);
2684
2685
2686
2687
2688 fas216_cmd(info, CMD_NOP);
2689
2690 fas216_init_chip(info);
2691
2692 spin_unlock_irq(info->host->host_lock);
2693 return SUCCESS;
2694 }
2695
2696 #define TYPE_UNKNOWN 0
2697 #define TYPE_NCR53C90 1
2698 #define TYPE_NCR53C90A 2
2699 #define TYPE_NCR53C9x 3
2700 #define TYPE_Am53CF94 4
2701 #define TYPE_EmFAS216 5
2702 #define TYPE_QLFAS216 6
2703
2704 static char *chip_types[] = {
2705 "unknown",
2706 "NS NCR53C90",
2707 "NS NCR53C90A",
2708 "NS NCR53C9x",
2709 "AMD Am53CF94",
2710 "Emulex FAS216",
2711 "QLogic FAS216"
2712 };
2713
2714 static int fas216_detect_type(FAS216_Info *info)
2715 {
2716 int family, rev;
2717
2718
2719
2720
2721 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2722 udelay(50);
2723 fas216_writeb(info, REG_CMD, CMD_NOP);
2724
2725
2726
2727
2728 fas216_writeb(info, REG_CNTL3, 0);
2729 fas216_writeb(info, REG_CNTL2, CNTL2_S2FE);
2730
2731
2732
2733
2734
2735
2736 if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE)
2737 return TYPE_NCR53C90;
2738
2739
2740
2741
2742 fas216_writeb(info, REG_CNTL2, 0);
2743 fas216_writeb(info, REG_CNTL3, 0);
2744 fas216_writeb(info, REG_CNTL3, 5);
2745
2746
2747
2748
2749
2750 if (fas216_readb(info, REG_CNTL3) != 5)
2751 return TYPE_NCR53C90A;
2752
2753
2754
2755
2756 fas216_writeb(info, REG_CNTL3, 0);
2757
2758 fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK);
2759 fas216_writeb(info, REG_CNTL3, 0);
2760
2761 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2762 udelay(50);
2763 fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP);
2764
2765 fas216_writeb(info, REG_CNTL2, CNTL2_ENF);
2766 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2767 udelay(50);
2768 fas216_writeb(info, REG_CMD, CMD_NOP);
2769
2770 rev = fas216_readb(info, REG_ID);
2771 family = rev >> 3;
2772 rev &= 7;
2773
2774 switch (family) {
2775 case 0x01:
2776 if (rev == 4)
2777 return TYPE_Am53CF94;
2778 break;
2779
2780 case 0x02:
2781 switch (rev) {
2782 case 2:
2783 return TYPE_EmFAS216;
2784 case 3:
2785 return TYPE_QLFAS216;
2786 }
2787 break;
2788
2789 default:
2790 break;
2791 }
2792 printk("family %x rev %x\n", family, rev);
2793 return TYPE_NCR53C9x;
2794 }
2795
2796
2797
2798
2799
2800
2801
2802 static void fas216_reset_state(FAS216_Info *info)
2803 {
2804 int i;
2805
2806 fas216_checkmagic(info);
2807
2808 fas216_bus_reset(info);
2809
2810
2811
2812
2813 memset(info->busyluns, 0, sizeof(info->busyluns));
2814 info->scsi.disconnectable = 0;
2815 info->scsi.aborting = 0;
2816
2817 for (i = 0; i < 8; i++) {
2818 info->device[i].parity_enabled = 0;
2819 info->device[i].parity_check = 1;
2820 }
2821
2822
2823
2824
2825 while (queue_remove(&info->queues.disconnected) != NULL);
2826
2827
2828
2829
2830 info->SCpnt = NULL;
2831 info->reqSCpnt = NULL;
2832 info->rstSCpnt = NULL;
2833 info->origSCpnt = NULL;
2834 }
2835
2836
2837
2838
2839
2840
2841
2842
2843 int fas216_init(struct Scsi_Host *host)
2844 {
2845 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2846
2847 info->magic_start = MAGIC;
2848 info->magic_end = MAGIC;
2849 info->host = host;
2850 info->scsi.cfg[0] = host->this_id | CNTL1_PERE;
2851 info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE;
2852 info->scsi.cfg[2] = info->ifcfg.cntl3 |
2853 CNTL3_ADIDCHK | CNTL3_QTAG | CNTL3_G2CB | CNTL3_LBTM;
2854 info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod);
2855
2856 info->rst_dev_status = -1;
2857 info->rst_bus_status = -1;
2858 init_waitqueue_head(&info->eh_wait);
2859 timer_setup(&info->eh_timer, fas216_eh_timer, 0);
2860
2861 spin_lock_init(&info->host_lock);
2862
2863 memset(&info->stats, 0, sizeof(info->stats));
2864
2865 msgqueue_initialise(&info->scsi.msgs);
2866
2867 if (!queue_initialise(&info->queues.issue))
2868 return -ENOMEM;
2869
2870 if (!queue_initialise(&info->queues.disconnected)) {
2871 queue_free(&info->queues.issue);
2872 return -ENOMEM;
2873 }
2874
2875 return 0;
2876 }
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886 int fas216_add(struct Scsi_Host *host, struct device *dev)
2887 {
2888 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2889 int type, ret;
2890
2891 if (info->ifcfg.clockrate <= 10 || info->ifcfg.clockrate > 40) {
2892 printk(KERN_CRIT "fas216: invalid clock rate %u MHz\n",
2893 info->ifcfg.clockrate);
2894 return -EINVAL;
2895 }
2896
2897 fas216_reset_state(info);
2898 type = fas216_detect_type(info);
2899 info->scsi.type = chip_types[type];
2900
2901 udelay(300);
2902
2903
2904
2905
2906 fas216_init_chip(info);
2907
2908
2909
2910
2911
2912
2913 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR);
2914 fas216_writeb(info, REG_CMD, CMD_RESETSCSI);
2915
2916
2917
2918
2919 spin_unlock_irq(info->host->host_lock);
2920 msleep(100*1000/100);
2921 spin_lock_irq(info->host->host_lock);
2922
2923 fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]);
2924 fas216_readb(info, REG_INST);
2925
2926 fas216_checkmagic(info);
2927
2928 ret = scsi_add_host(host, dev);
2929 if (ret)
2930 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2931 else
2932 scsi_scan_host(host);
2933
2934 return ret;
2935 }
2936
2937 void fas216_remove(struct Scsi_Host *host)
2938 {
2939 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2940
2941 fas216_checkmagic(info);
2942 scsi_remove_host(host);
2943
2944 fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
2945 scsi_host_put(host);
2946 }
2947
2948
2949
2950
2951
2952
2953
2954 void fas216_release(struct Scsi_Host *host)
2955 {
2956 FAS216_Info *info = (FAS216_Info *)host->hostdata;
2957
2958 queue_free(&info->queues.disconnected);
2959 queue_free(&info->queues.issue);
2960 }
2961
2962 void fas216_print_host(FAS216_Info *info, struct seq_file *m)
2963 {
2964 seq_printf(m,
2965 "\n"
2966 "Chip : %s\n"
2967 " Address: 0x%p\n"
2968 " IRQ : %d\n"
2969 " DMA : %d\n",
2970 info->scsi.type, info->scsi.io_base,
2971 info->scsi.irq, info->scsi.dma);
2972 }
2973
2974 void fas216_print_stats(FAS216_Info *info, struct seq_file *m)
2975 {
2976 seq_printf(m, "\n"
2977 "Command Statistics:\n"
2978 " Queued : %u\n"
2979 " Issued : %u\n"
2980 " Completed : %u\n"
2981 " Reads : %u\n"
2982 " Writes : %u\n"
2983 " Others : %u\n"
2984 " Disconnects: %u\n"
2985 " Aborts : %u\n"
2986 " Bus resets : %u\n"
2987 " Host resets: %u\n",
2988 info->stats.queues, info->stats.removes,
2989 info->stats.fins, info->stats.reads,
2990 info->stats.writes, info->stats.miscs,
2991 info->stats.disconnects, info->stats.aborts,
2992 info->stats.bus_resets, info->stats.host_resets);
2993 }
2994
2995 void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
2996 {
2997 struct fas216_device *dev;
2998 struct scsi_device *scd;
2999
3000 seq_puts(m, "Device/Lun TaggedQ Parity Sync\n");
3001
3002 shost_for_each_device(scd, info->host) {
3003 dev = &info->device[scd->id];
3004 seq_printf(m, " %d/%llu ", scd->id, scd->lun);
3005 if (scd->tagged_supported)
3006 seq_printf(m, "%3sabled ",
3007 scd->simple_tags ? "en" : "dis");
3008 else
3009 seq_puts(m, "unsupported ");
3010
3011 seq_printf(m, "%3sabled ", dev->parity_enabled ? "en" : "dis");
3012
3013 if (dev->sof)
3014 seq_printf(m, "offset %d, %d ns\n",
3015 dev->sof, dev->period * 4);
3016 else
3017 seq_puts(m, "async\n");
3018 }
3019 }
3020
3021 EXPORT_SYMBOL(fas216_init);
3022 EXPORT_SYMBOL(fas216_add);
3023 EXPORT_SYMBOL(fas216_queue_command);
3024 EXPORT_SYMBOL(fas216_noqueue_command);
3025 EXPORT_SYMBOL(fas216_intr);
3026 EXPORT_SYMBOL(fas216_remove);
3027 EXPORT_SYMBOL(fas216_release);
3028 EXPORT_SYMBOL(fas216_eh_abort);
3029 EXPORT_SYMBOL(fas216_eh_device_reset);
3030 EXPORT_SYMBOL(fas216_eh_bus_reset);
3031 EXPORT_SYMBOL(fas216_eh_host_reset);
3032 EXPORT_SYMBOL(fas216_print_host);
3033 EXPORT_SYMBOL(fas216_print_stats);
3034 EXPORT_SYMBOL(fas216_print_devices);
3035
3036 MODULE_AUTHOR("Russell King");
3037 MODULE_DESCRIPTION("Generic FAS216/NCR53C9x driver core");
3038 MODULE_LICENSE("GPL");