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
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include "aic7xxx_osm.h"
0044 #include "aic7xxx_inline.h"
0045 #include "aicasm/aicasm_insformat.h"
0046
0047
0048 static const char *const ahc_chip_names[] = {
0049 "NONE",
0050 "aic7770",
0051 "aic7850",
0052 "aic7855",
0053 "aic7859",
0054 "aic7860",
0055 "aic7870",
0056 "aic7880",
0057 "aic7895",
0058 "aic7895C",
0059 "aic7890/91",
0060 "aic7896/97",
0061 "aic7892",
0062 "aic7899"
0063 };
0064
0065
0066
0067
0068 struct ahc_hard_error_entry {
0069 uint8_t errno;
0070 const char *errmesg;
0071 };
0072
0073 static const struct ahc_hard_error_entry ahc_hard_errors[] = {
0074 { ILLHADDR, "Illegal Host Access" },
0075 { ILLSADDR, "Illegal Sequencer Address referenced" },
0076 { ILLOPCODE, "Illegal Opcode in sequencer program" },
0077 { SQPARERR, "Sequencer Parity Error" },
0078 { DPARERR, "Data-path Parity Error" },
0079 { MPARERR, "Scratch or SCB Memory Parity Error" },
0080 { PCIERRSTAT, "PCI Error detected" },
0081 { CIOPARERR, "CIOBUS Parity Error" },
0082 };
0083 static const u_int num_errors = ARRAY_SIZE(ahc_hard_errors);
0084
0085 static const struct ahc_phase_table_entry ahc_phase_table[] =
0086 {
0087 { P_DATAOUT, NOP, "in Data-out phase" },
0088 { P_DATAIN, INITIATOR_ERROR, "in Data-in phase" },
0089 { P_DATAOUT_DT, NOP, "in DT Data-out phase" },
0090 { P_DATAIN_DT, INITIATOR_ERROR, "in DT Data-in phase" },
0091 { P_COMMAND, NOP, "in Command phase" },
0092 { P_MESGOUT, NOP, "in Message-out phase" },
0093 { P_STATUS, INITIATOR_ERROR, "in Status phase" },
0094 { P_MESGIN, MSG_PARITY_ERROR, "in Message-in phase" },
0095 { P_BUSFREE, NOP, "while idle" },
0096 { 0, NOP, "in unknown phase" }
0097 };
0098
0099
0100
0101
0102
0103 static const u_int num_phases = ARRAY_SIZE(ahc_phase_table) - 1;
0104
0105
0106
0107
0108
0109
0110 static const struct ahc_syncrate ahc_syncrates[] =
0111 {
0112
0113 { 0x42, 0x000, 9, "80.0" },
0114 { 0x03, 0x000, 10, "40.0" },
0115 { 0x04, 0x000, 11, "33.0" },
0116 { 0x05, 0x100, 12, "20.0" },
0117 { 0x06, 0x110, 15, "16.0" },
0118 { 0x07, 0x120, 18, "13.4" },
0119 { 0x08, 0x000, 25, "10.0" },
0120 { 0x19, 0x010, 31, "8.0" },
0121 { 0x1a, 0x020, 37, "6.67" },
0122 { 0x1b, 0x030, 43, "5.7" },
0123 { 0x1c, 0x040, 50, "5.0" },
0124 { 0x00, 0x050, 56, "4.4" },
0125 { 0x00, 0x060, 62, "4.0" },
0126 { 0x00, 0x070, 68, "3.6" },
0127 { 0x00, 0x000, 0, NULL }
0128 };
0129
0130
0131 #include "aic7xxx_seq.h"
0132
0133
0134 static void ahc_force_renegotiation(struct ahc_softc *ahc,
0135 struct ahc_devinfo *devinfo);
0136 static struct ahc_tmode_tstate*
0137 ahc_alloc_tstate(struct ahc_softc *ahc,
0138 u_int scsi_id, char channel);
0139 #ifdef AHC_TARGET_MODE
0140 static void ahc_free_tstate(struct ahc_softc *ahc,
0141 u_int scsi_id, char channel, int force);
0142 #endif
0143 static const struct ahc_syncrate*
0144 ahc_devlimited_syncrate(struct ahc_softc *ahc,
0145 struct ahc_initiator_tinfo *,
0146 u_int *period,
0147 u_int *ppr_options,
0148 role_t role);
0149 static void ahc_update_pending_scbs(struct ahc_softc *ahc);
0150 static void ahc_fetch_devinfo(struct ahc_softc *ahc,
0151 struct ahc_devinfo *devinfo);
0152 static void ahc_scb_devinfo(struct ahc_softc *ahc,
0153 struct ahc_devinfo *devinfo,
0154 struct scb *scb);
0155 static void ahc_assert_atn(struct ahc_softc *ahc);
0156 static void ahc_setup_initiator_msgout(struct ahc_softc *ahc,
0157 struct ahc_devinfo *devinfo,
0158 struct scb *scb);
0159 static void ahc_build_transfer_msg(struct ahc_softc *ahc,
0160 struct ahc_devinfo *devinfo);
0161 static void ahc_construct_sdtr(struct ahc_softc *ahc,
0162 struct ahc_devinfo *devinfo,
0163 u_int period, u_int offset);
0164 static void ahc_construct_wdtr(struct ahc_softc *ahc,
0165 struct ahc_devinfo *devinfo,
0166 u_int bus_width);
0167 static void ahc_construct_ppr(struct ahc_softc *ahc,
0168 struct ahc_devinfo *devinfo,
0169 u_int period, u_int offset,
0170 u_int bus_width, u_int ppr_options);
0171 static void ahc_clear_msg_state(struct ahc_softc *ahc);
0172 static void ahc_handle_proto_violation(struct ahc_softc *ahc);
0173 static void ahc_handle_message_phase(struct ahc_softc *ahc);
0174 typedef enum {
0175 AHCMSG_1B,
0176 AHCMSG_2B,
0177 AHCMSG_EXT
0178 } ahc_msgtype;
0179 static int ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type,
0180 u_int msgval, int full);
0181 static int ahc_parse_msg(struct ahc_softc *ahc,
0182 struct ahc_devinfo *devinfo);
0183 static int ahc_handle_msg_reject(struct ahc_softc *ahc,
0184 struct ahc_devinfo *devinfo);
0185 static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc,
0186 struct ahc_devinfo *devinfo);
0187 static void ahc_reinitialize_dataptrs(struct ahc_softc *ahc);
0188 static void ahc_handle_devreset(struct ahc_softc *ahc,
0189 struct ahc_devinfo *devinfo,
0190 cam_status status, char *message,
0191 int verbose_level);
0192 #ifdef AHC_TARGET_MODE
0193 static void ahc_setup_target_msgin(struct ahc_softc *ahc,
0194 struct ahc_devinfo *devinfo,
0195 struct scb *scb);
0196 #endif
0197
0198 static bus_dmamap_callback_t ahc_dmamap_cb;
0199 static void ahc_build_free_scb_list(struct ahc_softc *ahc);
0200 static int ahc_init_scbdata(struct ahc_softc *ahc);
0201 static void ahc_fini_scbdata(struct ahc_softc *ahc);
0202 static void ahc_qinfifo_requeue(struct ahc_softc *ahc,
0203 struct scb *prev_scb,
0204 struct scb *scb);
0205 static int ahc_qinfifo_count(struct ahc_softc *ahc);
0206 static u_int ahc_rem_scb_from_disc_list(struct ahc_softc *ahc,
0207 u_int prev, u_int scbptr);
0208 static void ahc_add_curscb_to_free_list(struct ahc_softc *ahc);
0209 static u_int ahc_rem_wscb(struct ahc_softc *ahc,
0210 u_int scbpos, u_int prev);
0211 static void ahc_reset_current_bus(struct ahc_softc *ahc);
0212 #ifdef AHC_DUMP_SEQ
0213 static void ahc_dumpseq(struct ahc_softc *ahc);
0214 #endif
0215 static int ahc_loadseq(struct ahc_softc *ahc);
0216 static int ahc_check_patch(struct ahc_softc *ahc,
0217 const struct patch **start_patch,
0218 u_int start_instr, u_int *skip_addr);
0219 static void ahc_download_instr(struct ahc_softc *ahc,
0220 u_int instrptr, uint8_t *dconsts);
0221 #ifdef AHC_TARGET_MODE
0222 static void ahc_queue_lstate_event(struct ahc_softc *ahc,
0223 struct ahc_tmode_lstate *lstate,
0224 u_int initiator_id,
0225 u_int event_type,
0226 u_int event_arg);
0227 static void ahc_update_scsiid(struct ahc_softc *ahc,
0228 u_int targid_mask);
0229 static int ahc_handle_target_cmd(struct ahc_softc *ahc,
0230 struct target_cmd *cmd);
0231 #endif
0232
0233 static u_int ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl);
0234 static void ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl);
0235 static void ahc_busy_tcl(struct ahc_softc *ahc,
0236 u_int tcl, u_int busyid);
0237
0238
0239 static void ahc_run_untagged_queues(struct ahc_softc *ahc);
0240 static void ahc_run_untagged_queue(struct ahc_softc *ahc,
0241 struct scb_tailq *queue);
0242
0243
0244 static void ahc_alloc_scbs(struct ahc_softc *ahc);
0245 static void ahc_shutdown(void *arg);
0246
0247
0248 static void ahc_clear_intstat(struct ahc_softc *ahc);
0249 static void ahc_run_qoutfifo(struct ahc_softc *ahc);
0250 #ifdef AHC_TARGET_MODE
0251 static void ahc_run_tqinfifo(struct ahc_softc *ahc, int paused);
0252 #endif
0253 static void ahc_handle_brkadrint(struct ahc_softc *ahc);
0254 static void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat);
0255 static void ahc_handle_scsiint(struct ahc_softc *ahc,
0256 u_int intstat);
0257 static void ahc_clear_critical_section(struct ahc_softc *ahc);
0258
0259
0260 static void ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
0261 static int ahc_abort_scbs(struct ahc_softc *ahc, int target,
0262 char channel, int lun, u_int tag,
0263 role_t role, uint32_t status);
0264 static void ahc_calc_residual(struct ahc_softc *ahc,
0265 struct scb *scb);
0266
0267
0268 static inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc);
0269 static inline void ahc_release_untagged_queues(struct ahc_softc *ahc);
0270
0271
0272
0273
0274
0275 static inline void
0276 ahc_freeze_untagged_queues(struct ahc_softc *ahc)
0277 {
0278 if ((ahc->flags & AHC_SCB_BTT) == 0)
0279 ahc->untagged_queue_lock++;
0280 }
0281
0282
0283
0284
0285
0286
0287
0288 static inline void
0289 ahc_release_untagged_queues(struct ahc_softc *ahc)
0290 {
0291 if ((ahc->flags & AHC_SCB_BTT) == 0) {
0292 ahc->untagged_queue_lock--;
0293 if (ahc->untagged_queue_lock == 0)
0294 ahc_run_untagged_queues(ahc);
0295 }
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 static void
0308 ahc_pause_bug_fix(struct ahc_softc *ahc)
0309 {
0310 if ((ahc->features & AHC_ULTRA2) != 0)
0311 (void)ahc_inb(ahc, CCSCBCTL);
0312 }
0313
0314
0315
0316
0317
0318 int
0319 ahc_is_paused(struct ahc_softc *ahc)
0320 {
0321 return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
0322 }
0323
0324
0325
0326
0327
0328
0329
0330
0331 void
0332 ahc_pause(struct ahc_softc *ahc)
0333 {
0334 ahc_outb(ahc, HCNTRL, ahc->pause);
0335
0336
0337
0338
0339
0340 while (ahc_is_paused(ahc) == 0)
0341 ;
0342
0343 ahc_pause_bug_fix(ahc);
0344 }
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 void
0357 ahc_unpause(struct ahc_softc *ahc)
0358 {
0359 if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
0360 ahc_outb(ahc, HCNTRL, ahc->unpause);
0361 }
0362
0363
0364 static struct ahc_dma_seg *
0365 ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr)
0366 {
0367 int sg_index;
0368
0369 sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg);
0370
0371 sg_index++;
0372
0373 return (&scb->sg_list[sg_index]);
0374 }
0375
0376 static uint32_t
0377 ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg)
0378 {
0379 int sg_index;
0380
0381
0382 sg_index = sg - &scb->sg_list[1];
0383
0384 return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list)));
0385 }
0386
0387 static uint32_t
0388 ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)
0389 {
0390 return (ahc->scb_data->hscb_busaddr
0391 + (sizeof(struct hardware_scb) * index));
0392 }
0393
0394 static void
0395 ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)
0396 {
0397 ahc_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,
0398 ahc->scb_data->hscb_dmamap,
0399 (scb->hscb - ahc->hscbs) * sizeof(*scb->hscb),
0400 sizeof(*scb->hscb), op);
0401 }
0402
0403 void
0404 ahc_sync_sglist(struct ahc_softc *ahc, struct scb *scb, int op)
0405 {
0406 if (scb->sg_count == 0)
0407 return;
0408
0409 ahc_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,
0410 (scb->sg_list - scb->sg_map->sg_vaddr)
0411 * sizeof(struct ahc_dma_seg),
0412 sizeof(struct ahc_dma_seg) * scb->sg_count, op);
0413 }
0414
0415 #ifdef AHC_TARGET_MODE
0416 static uint32_t
0417 ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index)
0418 {
0419 return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo);
0420 }
0421 #endif
0422
0423
0424
0425
0426
0427
0428 static void
0429 ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)
0430 {
0431 uint32_t sgptr;
0432
0433 sgptr = ahc_le32toh(scb->hscb->sgptr);
0434 if ((sgptr & SG_RESID_VALID) != 0)
0435 ahc_calc_residual(ahc, scb);
0436 }
0437
0438
0439
0440
0441
0442 struct ahc_initiator_tinfo *
0443 ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
0444 u_int remote_id, struct ahc_tmode_tstate **tstate)
0445 {
0446
0447
0448
0449
0450
0451
0452 if (channel == 'B')
0453 our_id += 8;
0454 *tstate = ahc->enabled_targets[our_id];
0455 return (&(*tstate)->transinfo[remote_id]);
0456 }
0457
0458 uint16_t
0459 ahc_inw(struct ahc_softc *ahc, u_int port)
0460 {
0461 uint16_t r = ahc_inb(ahc, port+1) << 8;
0462 return r | ahc_inb(ahc, port);
0463 }
0464
0465 void
0466 ahc_outw(struct ahc_softc *ahc, u_int port, u_int value)
0467 {
0468 ahc_outb(ahc, port, value & 0xFF);
0469 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
0470 }
0471
0472 uint32_t
0473 ahc_inl(struct ahc_softc *ahc, u_int port)
0474 {
0475 return ((ahc_inb(ahc, port))
0476 | (ahc_inb(ahc, port+1) << 8)
0477 | (ahc_inb(ahc, port+2) << 16)
0478 | (ahc_inb(ahc, port+3) << 24));
0479 }
0480
0481 void
0482 ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value)
0483 {
0484 ahc_outb(ahc, port, (value) & 0xFF);
0485 ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);
0486 ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);
0487 ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);
0488 }
0489
0490 uint64_t
0491 ahc_inq(struct ahc_softc *ahc, u_int port)
0492 {
0493 return ((ahc_inb(ahc, port))
0494 | (ahc_inb(ahc, port+1) << 8)
0495 | (ahc_inb(ahc, port+2) << 16)
0496 | (((uint64_t)ahc_inb(ahc, port+3)) << 24)
0497 | (((uint64_t)ahc_inb(ahc, port+4)) << 32)
0498 | (((uint64_t)ahc_inb(ahc, port+5)) << 40)
0499 | (((uint64_t)ahc_inb(ahc, port+6)) << 48)
0500 | (((uint64_t)ahc_inb(ahc, port+7)) << 56));
0501 }
0502
0503 void
0504 ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value)
0505 {
0506 ahc_outb(ahc, port, value & 0xFF);
0507 ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
0508 ahc_outb(ahc, port+2, (value >> 16) & 0xFF);
0509 ahc_outb(ahc, port+3, (value >> 24) & 0xFF);
0510 ahc_outb(ahc, port+4, (value >> 32) & 0xFF);
0511 ahc_outb(ahc, port+5, (value >> 40) & 0xFF);
0512 ahc_outb(ahc, port+6, (value >> 48) & 0xFF);
0513 ahc_outb(ahc, port+7, (value >> 56) & 0xFF);
0514 }
0515
0516
0517
0518
0519 struct scb *
0520 ahc_get_scb(struct ahc_softc *ahc)
0521 {
0522 struct scb *scb;
0523
0524 if ((scb = SLIST_FIRST(&ahc->scb_data->free_scbs)) == NULL) {
0525 ahc_alloc_scbs(ahc);
0526 scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
0527 if (scb == NULL)
0528 return (NULL);
0529 }
0530 SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
0531 return (scb);
0532 }
0533
0534
0535
0536
0537 void
0538 ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)
0539 {
0540 struct hardware_scb *hscb;
0541
0542 hscb = scb->hscb;
0543
0544 ahc->scb_data->scbindex[hscb->tag] = NULL;
0545 scb->flags = SCB_FREE;
0546 hscb->control = 0;
0547
0548 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
0549
0550
0551 ahc_platform_scb_free(ahc, scb);
0552 }
0553
0554 struct scb *
0555 ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)
0556 {
0557 struct scb* scb;
0558
0559 scb = ahc->scb_data->scbindex[tag];
0560 if (scb != NULL)
0561 ahc_sync_scb(ahc, scb,
0562 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
0563 return (scb);
0564 }
0565
0566 static void
0567 ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb)
0568 {
0569 struct hardware_scb *q_hscb;
0570 u_int saved_tag;
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584 q_hscb = ahc->next_queued_scb->hscb;
0585 saved_tag = q_hscb->tag;
0586 memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
0587 if ((scb->flags & SCB_CDB32_PTR) != 0) {
0588 q_hscb->shared_data.cdb_ptr =
0589 ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
0590 + offsetof(struct hardware_scb, cdb32));
0591 }
0592 q_hscb->tag = saved_tag;
0593 q_hscb->next = scb->hscb->tag;
0594
0595
0596 ahc->next_queued_scb->hscb = scb->hscb;
0597 scb->hscb = q_hscb;
0598
0599
0600 ahc->scb_data->scbindex[scb->hscb->tag] = scb;
0601 }
0602
0603
0604
0605
0606 void
0607 ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)
0608 {
0609 ahc_swap_with_next_hscb(ahc, scb);
0610
0611 if (scb->hscb->tag == SCB_LIST_NULL
0612 || scb->hscb->next == SCB_LIST_NULL)
0613 panic("Attempt to queue invalid SCB tag %x:%x\n",
0614 scb->hscb->tag, scb->hscb->next);
0615
0616
0617
0618
0619 scb->hscb->lun &= LID;
0620 if (ahc_get_transfer_length(scb) & 0x1)
0621 scb->hscb->lun |= SCB_XFERLEN_ODD;
0622
0623
0624
0625
0626 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
0627
0628
0629
0630
0631
0632 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
0633
0634
0635 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
0636 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
0637 } else {
0638 if ((ahc->features & AHC_AUTOPAUSE) == 0)
0639 ahc_pause(ahc);
0640 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
0641 if ((ahc->features & AHC_AUTOPAUSE) == 0)
0642 ahc_unpause(ahc);
0643 }
0644 }
0645
0646 struct scsi_sense_data *
0647 ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb)
0648 {
0649 int offset;
0650
0651 offset = scb - ahc->scb_data->scbarray;
0652 return (&ahc->scb_data->sense[offset]);
0653 }
0654
0655 static uint32_t
0656 ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)
0657 {
0658 int offset;
0659
0660 offset = scb - ahc->scb_data->scbarray;
0661 return (ahc->scb_data->sense_busaddr
0662 + (offset * sizeof(struct scsi_sense_data)));
0663 }
0664
0665
0666 static void
0667 ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
0668 {
0669 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
0670 0, 256, op);
0671 }
0672
0673 static void
0674 ahc_sync_tqinfifo(struct ahc_softc *ahc, int op)
0675 {
0676 #ifdef AHC_TARGET_MODE
0677 if ((ahc->flags & AHC_TARGETROLE) != 0) {
0678 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
0679 ahc->shared_data_dmamap,
0680 ahc_targetcmd_offset(ahc, 0),
0681 sizeof(struct target_cmd) * AHC_TMODE_CMDS,
0682 op);
0683 }
0684 #endif
0685 }
0686
0687
0688
0689
0690
0691 #define AHC_RUN_QOUTFIFO 0x1
0692 #define AHC_RUN_TQINFIFO 0x2
0693 static u_int
0694 ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)
0695 {
0696 u_int retval;
0697
0698 retval = 0;
0699 ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
0700 ahc->qoutfifonext, 1,
0701 BUS_DMASYNC_POSTREAD);
0702 if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
0703 retval |= AHC_RUN_QOUTFIFO;
0704 #ifdef AHC_TARGET_MODE
0705 if ((ahc->flags & AHC_TARGETROLE) != 0
0706 && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
0707 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
0708 ahc->shared_data_dmamap,
0709 ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),
0710 sizeof(struct target_cmd),
0711 BUS_DMASYNC_POSTREAD);
0712 if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)
0713 retval |= AHC_RUN_TQINFIFO;
0714 }
0715 #endif
0716 return (retval);
0717 }
0718
0719
0720
0721
0722 int
0723 ahc_intr(struct ahc_softc *ahc)
0724 {
0725 u_int intstat;
0726
0727 if ((ahc->pause & INTEN) == 0) {
0728
0729
0730
0731
0732
0733
0734 return (0);
0735 }
0736
0737
0738
0739
0740
0741
0742 if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
0743 && (ahc_check_cmdcmpltqueues(ahc) != 0))
0744 intstat = CMDCMPLT;
0745 else {
0746 intstat = ahc_inb(ahc, INTSTAT);
0747 }
0748
0749 if ((intstat & INT_PEND) == 0) {
0750 #if AHC_PCI_CONFIG > 0
0751 if (ahc->unsolicited_ints > 500) {
0752 ahc->unsolicited_ints = 0;
0753 if ((ahc->chip & AHC_PCI) != 0
0754 && (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
0755 ahc->bus_intr(ahc);
0756 }
0757 #endif
0758 ahc->unsolicited_ints++;
0759 return (0);
0760 }
0761 ahc->unsolicited_ints = 0;
0762
0763 if (intstat & CMDCMPLT) {
0764 ahc_outb(ahc, CLRINT, CLRCMDINT);
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774 ahc_flush_device_writes(ahc);
0775 ahc_run_qoutfifo(ahc);
0776 #ifdef AHC_TARGET_MODE
0777 if ((ahc->flags & AHC_TARGETROLE) != 0)
0778 ahc_run_tqinfifo(ahc, FALSE);
0779 #endif
0780 }
0781
0782
0783
0784
0785
0786 if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {
0787
0788 } else if (intstat & BRKADRINT) {
0789 ahc_handle_brkadrint(ahc);
0790 } else if ((intstat & (SEQINT|SCSIINT)) != 0) {
0791
0792 ahc_pause_bug_fix(ahc);
0793
0794 if ((intstat & SEQINT) != 0)
0795 ahc_handle_seqint(ahc, intstat);
0796
0797 if ((intstat & SCSIINT) != 0)
0798 ahc_handle_scsiint(ahc, intstat);
0799 }
0800 return (1);
0801 }
0802
0803
0804
0805
0806
0807 static void
0808 ahc_restart(struct ahc_softc *ahc)
0809 {
0810 uint8_t sblkctl;
0811
0812 ahc_pause(ahc);
0813
0814
0815 ahc_clear_msg_state(ahc);
0816
0817 ahc_outb(ahc, SCSISIGO, 0);
0818 ahc_outb(ahc, MSG_OUT, NOP);
0819 ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
0820 ahc_outb(ahc, LASTPHASE, P_BUSFREE);
0821 ahc_outb(ahc, SAVED_SCSIID, 0xFF);
0822 ahc_outb(ahc, SAVED_LUN, 0xFF);
0823
0824
0825
0826
0827
0828
0829
0830
0831 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
0832
0833
0834 ahc_outb(ahc, SCSISEQ,
0835 ahc_inb(ahc, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
0836 if ((ahc->features & AHC_CMD_CHAN) != 0) {
0837
0838 ahc_outb(ahc, CCSCBCNT, 0);
0839 ahc_outb(ahc, CCSGCTL, 0);
0840 ahc_outb(ahc, CCSCBCTL, 0);
0841 }
0842
0843
0844
0845
0846
0847 if ((ahc_inb(ahc, SEQ_FLAGS2) & SCB_DMA) != 0) {
0848 ahc_add_curscb_to_free_list(ahc);
0849 ahc_outb(ahc, SEQ_FLAGS2,
0850 ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
0851 }
0852
0853
0854
0855
0856
0857
0858 ahc_outb(ahc, CLRINT, CLRSEQINT);
0859
0860 ahc_outb(ahc, MWI_RESIDUAL, 0);
0861 ahc_outb(ahc, SEQCTL, ahc->seqctl);
0862 ahc_outb(ahc, SEQADDR0, 0);
0863 ahc_outb(ahc, SEQADDR1, 0);
0864
0865
0866
0867
0868 sblkctl = ahc_inb(ahc, SBLKCTL);
0869 ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON)));
0870
0871 ahc_unpause(ahc);
0872 }
0873
0874
0875 static void
0876 ahc_run_qoutfifo(struct ahc_softc *ahc)
0877 {
0878 struct scb *scb;
0879 u_int scb_index;
0880
0881 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
0882 while (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL) {
0883
0884 scb_index = ahc->qoutfifo[ahc->qoutfifonext];
0885 if ((ahc->qoutfifonext & 0x03) == 0x03) {
0886 u_int modnext;
0887
0888
0889
0890
0891
0892
0893
0894
0895 modnext = ahc->qoutfifonext & ~0x3;
0896 *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
0897 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
0898 ahc->shared_data_dmamap,
0899 modnext, 4,
0900 BUS_DMASYNC_PREREAD);
0901 }
0902 ahc->qoutfifonext++;
0903
0904 scb = ahc_lookup_scb(ahc, scb_index);
0905 if (scb == NULL) {
0906 printk("%s: WARNING no command for scb %d "
0907 "(cmdcmplt)\nQOUTPOS = %d\n",
0908 ahc_name(ahc), scb_index,
0909 (ahc->qoutfifonext - 1) & 0xFF);
0910 continue;
0911 }
0912
0913
0914
0915
0916
0917 ahc_update_residual(ahc, scb);
0918 ahc_done(ahc, scb);
0919 }
0920 }
0921
0922 static void
0923 ahc_run_untagged_queues(struct ahc_softc *ahc)
0924 {
0925 int i;
0926
0927 for (i = 0; i < 16; i++)
0928 ahc_run_untagged_queue(ahc, &ahc->untagged_queues[i]);
0929 }
0930
0931 static void
0932 ahc_run_untagged_queue(struct ahc_softc *ahc, struct scb_tailq *queue)
0933 {
0934 struct scb *scb;
0935
0936 if (ahc->untagged_queue_lock != 0)
0937 return;
0938
0939 if ((scb = TAILQ_FIRST(queue)) != NULL
0940 && (scb->flags & SCB_ACTIVE) == 0) {
0941 scb->flags |= SCB_ACTIVE;
0942 ahc_queue_scb(ahc, scb);
0943 }
0944 }
0945
0946
0947 static void
0948 ahc_handle_brkadrint(struct ahc_softc *ahc)
0949 {
0950
0951
0952
0953
0954 int i;
0955 int error;
0956
0957 error = ahc_inb(ahc, ERROR);
0958 for (i = 0; error != 1 && i < num_errors; i++)
0959 error >>= 1;
0960 printk("%s: brkadrint, %s at seqaddr = 0x%x\n",
0961 ahc_name(ahc), ahc_hard_errors[i].errmesg,
0962 ahc_inb(ahc, SEQADDR0) |
0963 (ahc_inb(ahc, SEQADDR1) << 8));
0964
0965 ahc_dump_card_state(ahc);
0966
0967
0968 ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
0969 CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_UNKNOWN,
0970 CAM_NO_HBA);
0971
0972
0973 ahc_shutdown(ahc);
0974 }
0975
0976 static void
0977 ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
0978 {
0979 struct scb *scb;
0980 struct ahc_devinfo devinfo;
0981
0982 ahc_fetch_devinfo(ahc, &devinfo);
0983
0984
0985
0986
0987
0988
0989
0990 ahc_outb(ahc, CLRINT, CLRSEQINT);
0991 switch (intstat & SEQINT_MASK) {
0992 case BAD_STATUS:
0993 {
0994 u_int scb_index;
0995 struct hardware_scb *hscb;
0996
0997
0998
0999
1000
1001
1002 ahc_outb(ahc, RETURN_1, 0);
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 scb_index = ahc_inb(ahc, SCB_TAG);
1014 scb = ahc_lookup_scb(ahc, scb_index);
1015 if (scb == NULL) {
1016 ahc_print_devinfo(ahc, &devinfo);
1017 printk("ahc_intr - referenced scb "
1018 "not valid during seqint 0x%x scb(%d)\n",
1019 intstat, scb_index);
1020 ahc_dump_card_state(ahc);
1021 panic("for safety");
1022 goto unpause;
1023 }
1024
1025 hscb = scb->hscb;
1026
1027
1028 if ((scb->flags & SCB_SENSE) != 0) {
1029
1030
1031
1032
1033
1034 scb->flags &= ~SCB_SENSE;
1035 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
1036 break;
1037 }
1038 ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
1039
1040 ahc_freeze_devq(ahc, scb);
1041 ahc_freeze_scb(scb);
1042 ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
1043 switch (hscb->shared_data.status.scsi_status) {
1044 case SAM_STAT_GOOD:
1045 printk("%s: Interrupted for status of 0???\n",
1046 ahc_name(ahc));
1047 break;
1048 case SAM_STAT_COMMAND_TERMINATED:
1049 case SAM_STAT_CHECK_CONDITION:
1050 {
1051 struct ahc_dma_seg *sg;
1052 struct scsi_sense *sc;
1053 struct ahc_initiator_tinfo *targ_info;
1054 struct ahc_tmode_tstate *tstate;
1055 struct ahc_transinfo *tinfo;
1056 #ifdef AHC_DEBUG
1057 if (ahc_debug & AHC_SHOW_SENSE) {
1058 ahc_print_path(ahc, scb);
1059 printk("SCB %d: requests Check Status\n",
1060 scb->hscb->tag);
1061 }
1062 #endif
1063
1064 if (ahc_perform_autosense(scb) == 0)
1065 break;
1066
1067 targ_info = ahc_fetch_transinfo(ahc,
1068 devinfo.channel,
1069 devinfo.our_scsiid,
1070 devinfo.target,
1071 &tstate);
1072 tinfo = &targ_info->curr;
1073 sg = scb->sg_list;
1074 sc = (struct scsi_sense *)(&hscb->shared_data.cdb);
1075
1076
1077
1078 ahc_update_residual(ahc, scb);
1079 #ifdef AHC_DEBUG
1080 if (ahc_debug & AHC_SHOW_SENSE) {
1081 ahc_print_path(ahc, scb);
1082 printk("Sending Sense\n");
1083 }
1084 #endif
1085 sg->addr = ahc_get_sense_bufaddr(ahc, scb);
1086 sg->len = ahc_get_sense_bufsize(ahc, scb);
1087 sg->len |= AHC_DMA_LAST_SEG;
1088
1089
1090 sg->addr = ahc_htole32(sg->addr);
1091 sg->len = ahc_htole32(sg->len);
1092
1093 sc->opcode = REQUEST_SENSE;
1094 sc->byte2 = 0;
1095 if (tinfo->protocol_version <= SCSI_REV_2
1096 && SCB_GET_LUN(scb) < 8)
1097 sc->byte2 = SCB_GET_LUN(scb) << 5;
1098 sc->unused[0] = 0;
1099 sc->unused[1] = 0;
1100 sc->length = sg->len;
1101 sc->control = 0;
1102
1103
1104
1105
1106
1107
1108
1109
1110 hscb->control = 0;
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 if (ahc_get_residual(scb)
1121 == ahc_get_transfer_length(scb)) {
1122 ahc_update_neg_request(ahc, &devinfo,
1123 tstate, targ_info,
1124 AHC_NEG_IF_NON_ASYNC);
1125 }
1126 if (tstate->auto_negotiate & devinfo.target_mask) {
1127 hscb->control |= MK_MESSAGE;
1128 scb->flags &= ~SCB_NEGOTIATE;
1129 scb->flags |= SCB_AUTO_NEGOTIATE;
1130 }
1131 hscb->cdb_len = sizeof(*sc);
1132 hscb->dataptr = sg->addr;
1133 hscb->datacnt = sg->len;
1134 hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
1135 hscb->sgptr = ahc_htole32(hscb->sgptr);
1136 scb->sg_count = 1;
1137 scb->flags |= SCB_SENSE;
1138 ahc_qinfifo_requeue_tail(ahc, scb);
1139 ahc_outb(ahc, RETURN_1, SEND_SENSE);
1140
1141
1142
1143
1144 ahc_scb_timer_reset(scb, 5 * 1000000);
1145 break;
1146 }
1147 default:
1148 break;
1149 }
1150 break;
1151 }
1152 case NO_MATCH:
1153 {
1154
1155 ahc_outb(ahc, SCSISEQ,
1156 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
1157
1158 printk("%s:%c:%d: no active SCB for reconnecting "
1159 "target - issuing BUS DEVICE RESET\n",
1160 ahc_name(ahc), devinfo.channel, devinfo.target);
1161 printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
1162 "ARG_1 == 0x%x ACCUM = 0x%x\n",
1163 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
1164 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
1165 printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
1166 "SINDEX == 0x%x\n",
1167 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
1168 ahc_index_busy_tcl(ahc,
1169 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
1170 ahc_inb(ahc, SAVED_LUN))),
1171 ahc_inb(ahc, SINDEX));
1172 printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1173 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
1174 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
1175 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
1176 ahc_inb(ahc, SCB_CONTROL));
1177 printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
1178 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
1179 printk("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0));
1180 printk("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL));
1181 ahc_dump_card_state(ahc);
1182 ahc->msgout_buf[0] = TARGET_RESET;
1183 ahc->msgout_len = 1;
1184 ahc->msgout_index = 0;
1185 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
1186 ahc_outb(ahc, MSG_OUT, HOST_MSG);
1187 ahc_assert_atn(ahc);
1188 break;
1189 }
1190 case SEND_REJECT:
1191 {
1192 u_int rejbyte = ahc_inb(ahc, ACCUM);
1193 printk("%s:%c:%d: Warning - unknown message received from "
1194 "target (0x%x). Rejecting\n",
1195 ahc_name(ahc), devinfo.channel, devinfo.target, rejbyte);
1196 break;
1197 }
1198 case PROTO_VIOLATION:
1199 {
1200 ahc_handle_proto_violation(ahc);
1201 break;
1202 }
1203 case IGN_WIDE_RES:
1204 ahc_handle_ign_wide_residue(ahc, &devinfo);
1205 break;
1206 case PDATA_REINIT:
1207 ahc_reinitialize_dataptrs(ahc);
1208 break;
1209 case BAD_PHASE:
1210 {
1211 u_int lastphase;
1212
1213 lastphase = ahc_inb(ahc, LASTPHASE);
1214 printk("%s:%c:%d: unknown scsi bus phase %x, "
1215 "lastphase = 0x%x. Attempting to continue\n",
1216 ahc_name(ahc), devinfo.channel, devinfo.target,
1217 lastphase, ahc_inb(ahc, SCSISIGI));
1218 break;
1219 }
1220 case MISSED_BUSFREE:
1221 {
1222 u_int lastphase;
1223
1224 lastphase = ahc_inb(ahc, LASTPHASE);
1225 printk("%s:%c:%d: Missed busfree. "
1226 "Lastphase = 0x%x, Curphase = 0x%x\n",
1227 ahc_name(ahc), devinfo.channel, devinfo.target,
1228 lastphase, ahc_inb(ahc, SCSISIGI));
1229 ahc_restart(ahc);
1230 return;
1231 }
1232 case HOST_MSG_LOOP:
1233 {
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245 if (ahc->msg_type == MSG_TYPE_NONE) {
1246 struct scb *scb;
1247 u_int scb_index;
1248 u_int bus_phase;
1249
1250 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1251 if (bus_phase != P_MESGIN
1252 && bus_phase != P_MESGOUT) {
1253 printk("ahc_intr: HOST_MSG_LOOP bad "
1254 "phase 0x%x\n",
1255 bus_phase);
1256
1257
1258
1259
1260 ahc_clear_intstat(ahc);
1261 ahc_restart(ahc);
1262 return;
1263 }
1264
1265 scb_index = ahc_inb(ahc, SCB_TAG);
1266 scb = ahc_lookup_scb(ahc, scb_index);
1267 if (devinfo.role == ROLE_INITIATOR) {
1268 if (bus_phase == P_MESGOUT) {
1269 if (scb == NULL)
1270 panic("HOST_MSG_LOOP with "
1271 "invalid SCB %x\n",
1272 scb_index);
1273
1274 ahc_setup_initiator_msgout(ahc,
1275 &devinfo,
1276 scb);
1277 } else {
1278 ahc->msg_type =
1279 MSG_TYPE_INITIATOR_MSGIN;
1280 ahc->msgin_index = 0;
1281 }
1282 }
1283 #ifdef AHC_TARGET_MODE
1284 else {
1285 if (bus_phase == P_MESGOUT) {
1286 ahc->msg_type =
1287 MSG_TYPE_TARGET_MSGOUT;
1288 ahc->msgin_index = 0;
1289 } else
1290 ahc_setup_target_msgin(ahc,
1291 &devinfo,
1292 scb);
1293 }
1294 #endif
1295 }
1296
1297 ahc_handle_message_phase(ahc);
1298 break;
1299 }
1300 case PERR_DETECTED:
1301 {
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313 if ((intstat & SCSIINT) == 0
1314 && (ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0) {
1315
1316 if ((ahc->features & AHC_DT) == 0) {
1317 u_int curphase;
1318
1319
1320
1321
1322
1323
1324
1325 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1326 ahc_outb(ahc, LASTPHASE, curphase);
1327 ahc_outb(ahc, SCSISIGO, curphase);
1328 }
1329 if ((ahc_inb(ahc, SCSISIGI) & (CDI|MSGI)) == 0) {
1330 int wait;
1331
1332
1333
1334
1335
1336
1337
1338 ahc_outb(ahc, SXFRCTL1,
1339 ahc_inb(ahc, SXFRCTL1) | BITBUCKET);
1340 wait = 5000;
1341 while (--wait != 0) {
1342 if ((ahc_inb(ahc, SCSISIGI)
1343 & (CDI|MSGI)) != 0)
1344 break;
1345 ahc_delay(100);
1346 }
1347 ahc_outb(ahc, SXFRCTL1,
1348 ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
1349 if (wait == 0) {
1350 struct scb *scb;
1351 u_int scb_index;
1352
1353 ahc_print_devinfo(ahc, &devinfo);
1354 printk("Unable to clear parity error. "
1355 "Resetting bus.\n");
1356 scb_index = ahc_inb(ahc, SCB_TAG);
1357 scb = ahc_lookup_scb(ahc, scb_index);
1358 if (scb != NULL)
1359 ahc_set_transaction_status(scb,
1360 CAM_UNCOR_PARITY);
1361 ahc_reset_channel(ahc, devinfo.channel,
1362 TRUE);
1363 }
1364 } else {
1365 ahc_inb(ahc, SCSIDATL);
1366 }
1367 }
1368 break;
1369 }
1370 case DATA_OVERRUN:
1371 {
1372
1373
1374
1375
1376
1377
1378
1379
1380 u_int scbindex = ahc_inb(ahc, SCB_TAG);
1381 u_int lastphase = ahc_inb(ahc, LASTPHASE);
1382 u_int i;
1383
1384 scb = ahc_lookup_scb(ahc, scbindex);
1385 for (i = 0; i < num_phases; i++) {
1386 if (lastphase == ahc_phase_table[i].phase)
1387 break;
1388 }
1389 ahc_print_path(ahc, scb);
1390 printk("data overrun detected %s."
1391 " Tag == 0x%x.\n",
1392 ahc_phase_table[i].phasemsg,
1393 scb->hscb->tag);
1394 ahc_print_path(ahc, scb);
1395 printk("%s seen Data Phase. Length = %ld. NumSGs = %d.\n",
1396 ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
1397 ahc_get_transfer_length(scb), scb->sg_count);
1398 if (scb->sg_count > 0) {
1399 for (i = 0; i < scb->sg_count; i++) {
1400
1401 printk("sg[%d] - Addr 0x%x%x : Length %d\n",
1402 i,
1403 (ahc_le32toh(scb->sg_list[i].len) >> 24
1404 & SG_HIGH_ADDR_BITS),
1405 ahc_le32toh(scb->sg_list[i].addr),
1406 ahc_le32toh(scb->sg_list[i].len)
1407 & AHC_SG_LEN_MASK);
1408 }
1409 }
1410
1411
1412
1413
1414 ahc_freeze_devq(ahc, scb);
1415 if ((scb->flags & SCB_SENSE) == 0) {
1416 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1417 } else {
1418 scb->flags &= ~SCB_SENSE;
1419 ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
1420 }
1421 ahc_freeze_scb(scb);
1422
1423 if ((ahc->features & AHC_ULTRA2) != 0) {
1424
1425
1426
1427
1428 ahc_outb(ahc, SXFRCTL0,
1429 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
1430 ahc_outb(ahc, SXFRCTL0,
1431 ahc_inb(ahc, SXFRCTL0) | CLRSTCNT|CLRCHN);
1432 }
1433 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
1434 u_int dscommand1;
1435
1436
1437 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
1438 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
1439 ahc_outb(ahc, HADDR, 0);
1440 ahc_outb(ahc, DSCOMMAND1, dscommand1);
1441 }
1442 break;
1443 }
1444 case MKMSG_FAILED:
1445 {
1446 u_int scbindex;
1447
1448 printk("%s:%c:%d:%d: Attempt to issue message failed\n",
1449 ahc_name(ahc), devinfo.channel, devinfo.target,
1450 devinfo.lun);
1451 scbindex = ahc_inb(ahc, SCB_TAG);
1452 scb = ahc_lookup_scb(ahc, scbindex);
1453 if (scb != NULL
1454 && (scb->flags & SCB_RECOVERY_SCB) != 0)
1455
1456
1457
1458
1459 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
1460 SCB_GET_CHANNEL(ahc, scb),
1461 SCB_GET_LUN(scb), scb->hscb->tag,
1462 ROLE_INITIATOR, 0,
1463 SEARCH_REMOVE);
1464 break;
1465 }
1466 case NO_FREE_SCB:
1467 {
1468 printk("%s: No free or disconnected SCBs\n", ahc_name(ahc));
1469 ahc_dump_card_state(ahc);
1470 panic("for safety");
1471 break;
1472 }
1473 case SCB_MISMATCH:
1474 {
1475 u_int scbptr;
1476
1477 scbptr = ahc_inb(ahc, SCBPTR);
1478 printk("Bogus TAG after DMA. SCBPTR %d, tag %d, our tag %d\n",
1479 scbptr, ahc_inb(ahc, ARG_1),
1480 ahc->scb_data->hscbs[scbptr].tag);
1481 ahc_dump_card_state(ahc);
1482 panic("for safety");
1483 break;
1484 }
1485 case OUT_OF_RANGE:
1486 {
1487 printk("%s: BTT calculation out of range\n", ahc_name(ahc));
1488 printk("SAVED_SCSIID == 0x%x, SAVED_LUN == 0x%x, "
1489 "ARG_1 == 0x%x ACCUM = 0x%x\n",
1490 ahc_inb(ahc, SAVED_SCSIID), ahc_inb(ahc, SAVED_LUN),
1491 ahc_inb(ahc, ARG_1), ahc_inb(ahc, ACCUM));
1492 printk("SEQ_FLAGS == 0x%x, SCBPTR == 0x%x, BTT == 0x%x, "
1493 "SINDEX == 0x%x\n, A == 0x%x\n",
1494 ahc_inb(ahc, SEQ_FLAGS), ahc_inb(ahc, SCBPTR),
1495 ahc_index_busy_tcl(ahc,
1496 BUILD_TCL(ahc_inb(ahc, SAVED_SCSIID),
1497 ahc_inb(ahc, SAVED_LUN))),
1498 ahc_inb(ahc, SINDEX),
1499 ahc_inb(ahc, ACCUM));
1500 printk("SCSIID == 0x%x, SCB_SCSIID == 0x%x, SCB_LUN == 0x%x, "
1501 "SCB_TAG == 0x%x, SCB_CONTROL == 0x%x\n",
1502 ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID),
1503 ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG),
1504 ahc_inb(ahc, SCB_CONTROL));
1505 printk("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n",
1506 ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI));
1507 ahc_dump_card_state(ahc);
1508 panic("for safety");
1509 break;
1510 }
1511 default:
1512 printk("ahc_intr: seqint, "
1513 "intstat == 0x%x, scsisigi = 0x%x\n",
1514 intstat, ahc_inb(ahc, SCSISIGI));
1515 break;
1516 }
1517 unpause:
1518
1519
1520
1521
1522
1523 ahc_unpause(ahc);
1524 }
1525
1526 static void
1527 ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat)
1528 {
1529 u_int scb_index;
1530 u_int status0;
1531 u_int status;
1532 struct scb *scb;
1533 char cur_channel;
1534 char intr_channel;
1535
1536 if ((ahc->features & AHC_TWIN) != 0
1537 && ((ahc_inb(ahc, SBLKCTL) & SELBUSB) != 0))
1538 cur_channel = 'B';
1539 else
1540 cur_channel = 'A';
1541 intr_channel = cur_channel;
1542
1543 if ((ahc->features & AHC_ULTRA2) != 0)
1544 status0 = ahc_inb(ahc, SSTAT0) & IOERR;
1545 else
1546 status0 = 0;
1547 status = ahc_inb(ahc, SSTAT1) & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1548 if (status == 0 && status0 == 0) {
1549 if ((ahc->features & AHC_TWIN) != 0) {
1550
1551 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1552 status = ahc_inb(ahc, SSTAT1)
1553 & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR);
1554 intr_channel = (cur_channel == 'A') ? 'B' : 'A';
1555 }
1556 if (status == 0) {
1557 printk("%s: Spurious SCSI interrupt\n", ahc_name(ahc));
1558 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1559 ahc_unpause(ahc);
1560 return;
1561 }
1562 }
1563
1564
1565 ahc_clear_critical_section(ahc);
1566
1567 scb_index = ahc_inb(ahc, SCB_TAG);
1568 scb = ahc_lookup_scb(ahc, scb_index);
1569 if (scb != NULL
1570 && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) != 0)
1571 scb = NULL;
1572
1573 if ((ahc->features & AHC_ULTRA2) != 0
1574 && (status0 & IOERR) != 0) {
1575 int now_lvd;
1576
1577 now_lvd = ahc_inb(ahc, SBLKCTL) & ENAB40;
1578 printk("%s: Transceiver State Has Changed to %s mode\n",
1579 ahc_name(ahc), now_lvd ? "LVD" : "SE");
1580 ahc_outb(ahc, CLRSINT0, CLRIOERR);
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 ahc_reset_channel(ahc, intr_channel,
1592 now_lvd == 0);
1593 } else if ((status & SCSIRSTI) != 0) {
1594 printk("%s: Someone reset channel %c\n",
1595 ahc_name(ahc), intr_channel);
1596 if (intr_channel != cur_channel)
1597 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB);
1598 ahc_reset_channel(ahc, intr_channel, FALSE);
1599 } else if ((status & SCSIPERR) != 0) {
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610 struct ahc_devinfo devinfo;
1611 u_int mesg_out;
1612 u_int curphase;
1613 u_int errorphase;
1614 u_int lastphase;
1615 u_int scsirate;
1616 u_int i;
1617 u_int sstat2;
1618 int silent;
1619
1620 lastphase = ahc_inb(ahc, LASTPHASE);
1621 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
1622 sstat2 = ahc_inb(ahc, SSTAT2);
1623 ahc_outb(ahc, CLRSINT1, CLRSCSIPERR);
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635 if ((ahc_inb(ahc, SSTAT1) & SCSIPERR) != 0
1636 || curphase == P_DATAIN || curphase == P_DATAIN_DT)
1637 errorphase = curphase;
1638 else
1639 errorphase = lastphase;
1640
1641 for (i = 0; i < num_phases; i++) {
1642 if (errorphase == ahc_phase_table[i].phase)
1643 break;
1644 }
1645 mesg_out = ahc_phase_table[i].mesg_out;
1646 silent = FALSE;
1647 if (scb != NULL) {
1648 if (SCB_IS_SILENT(scb))
1649 silent = TRUE;
1650 else
1651 ahc_print_path(ahc, scb);
1652 scb->flags |= SCB_TRANSMISSION_ERROR;
1653 } else
1654 printk("%s:%c:%d: ", ahc_name(ahc), intr_channel,
1655 SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)));
1656 scsirate = ahc_inb(ahc, SCSIRATE);
1657 if (silent == FALSE) {
1658 printk("parity error detected %s. "
1659 "SEQADDR(0x%x) SCSIRATE(0x%x)\n",
1660 ahc_phase_table[i].phasemsg,
1661 ahc_inw(ahc, SEQADDR0),
1662 scsirate);
1663 if ((ahc->features & AHC_DT) != 0) {
1664 if ((sstat2 & CRCVALERR) != 0)
1665 printk("\tCRC Value Mismatch\n");
1666 if ((sstat2 & CRCENDERR) != 0)
1667 printk("\tNo terminal CRC packet "
1668 "received\n");
1669 if ((sstat2 & CRCREQERR) != 0)
1670 printk("\tIllegal CRC packet "
1671 "request\n");
1672 if ((sstat2 & DUAL_EDGE_ERR) != 0)
1673 printk("\tUnexpected %sDT Data Phase\n",
1674 (scsirate & SINGLE_EDGE)
1675 ? "" : "non-");
1676 }
1677 }
1678
1679 if ((ahc->features & AHC_DT) != 0
1680 && (sstat2 & DUAL_EDGE_ERR) != 0) {
1681
1682
1683
1684
1685
1686 mesg_out = INITIATOR_ERROR;
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696 if (mesg_out != NOP) {
1697 if (ahc->msg_type != MSG_TYPE_NONE)
1698 ahc->send_msg_perror = TRUE;
1699 else
1700 ahc_outb(ahc, MSG_OUT, mesg_out);
1701 }
1702
1703
1704
1705
1706
1707 ahc_fetch_devinfo(ahc, &devinfo);
1708 ahc_force_renegotiation(ahc, &devinfo);
1709
1710 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1711 ahc_unpause(ahc);
1712 } else if ((status & SELTO) != 0) {
1713 u_int scbptr;
1714
1715
1716 ahc_outb(ahc, SCSISEQ, 0);
1717
1718
1719 ahc_clear_msg_state(ahc);
1720
1721
1722 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1723 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRBUSFREE|CLRSCSIPERR);
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733 ahc_outb(ahc, CLRSINT0, CLRSELINGO);
1734
1735 scbptr = ahc_inb(ahc, WAITING_SCBH);
1736 ahc_outb(ahc, SCBPTR, scbptr);
1737 scb_index = ahc_inb(ahc, SCB_TAG);
1738
1739 scb = ahc_lookup_scb(ahc, scb_index);
1740 if (scb == NULL) {
1741 printk("%s: ahc_intr - referenced scb not "
1742 "valid during SELTO scb(%d, %d)\n",
1743 ahc_name(ahc), scbptr, scb_index);
1744 ahc_dump_card_state(ahc);
1745 } else {
1746 struct ahc_devinfo devinfo;
1747 #ifdef AHC_DEBUG
1748 if ((ahc_debug & AHC_SHOW_SELTO) != 0) {
1749 ahc_print_path(ahc, scb);
1750 printk("Saw Selection Timeout for SCB 0x%x\n",
1751 scb_index);
1752 }
1753 #endif
1754 ahc_scb_devinfo(ahc, &devinfo, scb);
1755 ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
1756 ahc_freeze_devq(ahc, scb);
1757
1758
1759
1760
1761
1762
1763
1764 ahc_handle_devreset(ahc, &devinfo,
1765 CAM_SEL_TIMEOUT,
1766 "Selection Timeout",
1767 1);
1768 }
1769 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1770 ahc_restart(ahc);
1771 } else if ((status & BUSFREE) != 0
1772 && (ahc_inb(ahc, SIMODE1) & ENBUSFREE) != 0) {
1773 struct ahc_devinfo devinfo;
1774 u_int lastphase;
1775 u_int saved_scsiid;
1776 u_int saved_lun;
1777 u_int target;
1778 u_int initiator_role_id;
1779 char channel;
1780 int printerror;
1781
1782
1783
1784
1785
1786
1787
1788 ahc_outb(ahc, SCSISEQ,
1789 ahc_inb(ahc, SCSISEQ) & (ENSELI|ENRSELI|ENAUTOATNP));
1790
1791
1792
1793
1794
1795
1796
1797 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE);
1798 ahc_outb(ahc, CLRSINT1, CLRBUSFREE|CLRSCSIPERR);
1799
1800
1801
1802
1803
1804
1805
1806 lastphase = ahc_inb(ahc, LASTPHASE);
1807 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
1808 saved_lun = ahc_inb(ahc, SAVED_LUN);
1809 target = SCSIID_TARGET(ahc, saved_scsiid);
1810 initiator_role_id = SCSIID_OUR_ID(saved_scsiid);
1811 channel = SCSIID_CHANNEL(ahc, saved_scsiid);
1812 ahc_compile_devinfo(&devinfo, initiator_role_id,
1813 target, saved_lun, channel, ROLE_INITIATOR);
1814 printerror = 1;
1815
1816 if (lastphase == P_MESGOUT) {
1817 u_int tag;
1818
1819 tag = SCB_LIST_NULL;
1820 if (ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK, TRUE)
1821 || ahc_sent_msg(ahc, AHCMSG_1B, ABORT_TASK_SET, TRUE)) {
1822 if (ahc->msgout_buf[ahc->msgout_index - 1]
1823 == ABORT_TASK)
1824 tag = scb->hscb->tag;
1825 ahc_print_path(ahc, scb);
1826 printk("SCB %d - Abort%s Completed.\n",
1827 scb->hscb->tag, tag == SCB_LIST_NULL ?
1828 "" : " Tag");
1829 ahc_abort_scbs(ahc, target, channel,
1830 saved_lun, tag,
1831 ROLE_INITIATOR,
1832 CAM_REQ_ABORTED);
1833 printerror = 0;
1834 } else if (ahc_sent_msg(ahc, AHCMSG_1B,
1835 TARGET_RESET, TRUE)) {
1836 ahc_compile_devinfo(&devinfo,
1837 initiator_role_id,
1838 target,
1839 CAM_LUN_WILDCARD,
1840 channel,
1841 ROLE_INITIATOR);
1842 ahc_handle_devreset(ahc, &devinfo,
1843 CAM_BDR_SENT,
1844 "Bus Device Reset",
1845 0);
1846 printerror = 0;
1847 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1848 EXTENDED_PPR, FALSE)) {
1849 struct ahc_initiator_tinfo *tinfo;
1850 struct ahc_tmode_tstate *tstate;
1851
1852
1853
1854
1855
1856 tinfo = ahc_fetch_transinfo(ahc,
1857 devinfo.channel,
1858 devinfo.our_scsiid,
1859 devinfo.target,
1860 &tstate);
1861 tinfo->curr.transport_version = 2;
1862 tinfo->goal.transport_version = 2;
1863 tinfo->goal.ppr_options = 0;
1864 ahc_qinfifo_requeue_tail(ahc, scb);
1865 printerror = 0;
1866 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1867 EXTENDED_WDTR, FALSE)) {
1868
1869
1870
1871
1872 ahc_set_width(ahc, &devinfo,
1873 MSG_EXT_WDTR_BUS_8_BIT,
1874 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1875 TRUE);
1876 ahc_qinfifo_requeue_tail(ahc, scb);
1877 printerror = 0;
1878 } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
1879 EXTENDED_SDTR, FALSE)) {
1880
1881
1882
1883
1884 ahc_set_syncrate(ahc, &devinfo,
1885 NULL,
1886 0, 0,
1887 0,
1888 AHC_TRANS_CUR|AHC_TRANS_GOAL,
1889 TRUE);
1890 ahc_qinfifo_requeue_tail(ahc, scb);
1891 printerror = 0;
1892 }
1893 }
1894 if (printerror != 0) {
1895 u_int i;
1896
1897 if (scb != NULL) {
1898 u_int tag;
1899
1900 if ((scb->hscb->control & TAG_ENB) != 0)
1901 tag = scb->hscb->tag;
1902 else
1903 tag = SCB_LIST_NULL;
1904 ahc_print_path(ahc, scb);
1905 ahc_abort_scbs(ahc, target, channel,
1906 SCB_GET_LUN(scb), tag,
1907 ROLE_INITIATOR,
1908 CAM_UNEXP_BUSFREE);
1909 } else {
1910
1911
1912
1913
1914 printk("%s: ", ahc_name(ahc));
1915 }
1916 for (i = 0; i < num_phases; i++) {
1917 if (lastphase == ahc_phase_table[i].phase)
1918 break;
1919 }
1920 if (lastphase != P_BUSFREE) {
1921
1922
1923
1924
1925
1926
1927 ahc_force_renegotiation(ahc, &devinfo);
1928 }
1929 printk("Unexpected busfree %s\n"
1930 "SEQADDR == 0x%x\n",
1931 ahc_phase_table[i].phasemsg,
1932 ahc_inb(ahc, SEQADDR0)
1933 | (ahc_inb(ahc, SEQADDR1) << 8));
1934 }
1935 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1936 ahc_restart(ahc);
1937 } else {
1938 printk("%s: Missing case in ahc_handle_scsiint. status = %x\n",
1939 ahc_name(ahc), status);
1940 ahc_outb(ahc, CLRINT, CLRSCSIINT);
1941 }
1942 }
1943
1944
1945
1946
1947
1948 static void
1949 ahc_force_renegotiation(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1950 {
1951 struct ahc_initiator_tinfo *targ_info;
1952 struct ahc_tmode_tstate *tstate;
1953
1954 targ_info = ahc_fetch_transinfo(ahc,
1955 devinfo->channel,
1956 devinfo->our_scsiid,
1957 devinfo->target,
1958 &tstate);
1959 ahc_update_neg_request(ahc, devinfo, tstate,
1960 targ_info, AHC_NEG_IF_NON_ASYNC);
1961 }
1962
1963 #define AHC_MAX_STEPS 2000
1964 static void
1965 ahc_clear_critical_section(struct ahc_softc *ahc)
1966 {
1967 int stepping;
1968 int steps;
1969 u_int simode0;
1970 u_int simode1;
1971
1972 if (ahc->num_critical_sections == 0)
1973 return;
1974
1975 stepping = FALSE;
1976 steps = 0;
1977 simode0 = 0;
1978 simode1 = 0;
1979 for (;;) {
1980 struct cs *cs;
1981 u_int seqaddr;
1982 u_int i;
1983
1984 seqaddr = ahc_inb(ahc, SEQADDR0)
1985 | (ahc_inb(ahc, SEQADDR1) << 8);
1986
1987
1988
1989
1990
1991
1992 if (seqaddr != 0)
1993 seqaddr -= 1;
1994 cs = ahc->critical_sections;
1995 for (i = 0; i < ahc->num_critical_sections; i++, cs++) {
1996 if (cs->begin < seqaddr && cs->end >= seqaddr)
1997 break;
1998 }
1999
2000 if (i == ahc->num_critical_sections)
2001 break;
2002
2003 if (steps > AHC_MAX_STEPS) {
2004 printk("%s: Infinite loop in critical section\n",
2005 ahc_name(ahc));
2006 ahc_dump_card_state(ahc);
2007 panic("critical section loop");
2008 }
2009
2010 steps++;
2011 if (stepping == FALSE) {
2012
2013
2014
2015
2016
2017
2018
2019 simode0 = ahc_inb(ahc, SIMODE0);
2020 ahc_outb(ahc, SIMODE0, 0);
2021 simode1 = ahc_inb(ahc, SIMODE1);
2022 if ((ahc->features & AHC_DT) != 0)
2023
2024
2025
2026
2027
2028
2029
2030
2031 ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
2032 else
2033 ahc_outb(ahc, SIMODE1, 0);
2034 ahc_outb(ahc, CLRINT, CLRSCSIINT);
2035 ahc_outb(ahc, SEQCTL, ahc->seqctl | STEP);
2036 stepping = TRUE;
2037 }
2038 if ((ahc->features & AHC_DT) != 0) {
2039 ahc_outb(ahc, CLRSINT1, CLRBUSFREE);
2040 ahc_outb(ahc, CLRINT, CLRSCSIINT);
2041 }
2042 ahc_outb(ahc, HCNTRL, ahc->unpause);
2043 while (!ahc_is_paused(ahc))
2044 ahc_delay(200);
2045 }
2046 if (stepping) {
2047 ahc_outb(ahc, SIMODE0, simode0);
2048 ahc_outb(ahc, SIMODE1, simode1);
2049 ahc_outb(ahc, SEQCTL, ahc->seqctl);
2050 }
2051 }
2052
2053
2054
2055
2056 static void
2057 ahc_clear_intstat(struct ahc_softc *ahc)
2058 {
2059
2060 ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
2061 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
2062 CLRREQINIT);
2063 ahc_flush_device_writes(ahc);
2064 ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
2065 ahc_flush_device_writes(ahc);
2066 ahc_outb(ahc, CLRINT, CLRSCSIINT);
2067 ahc_flush_device_writes(ahc);
2068 }
2069
2070
2071 #ifdef AHC_DEBUG
2072 uint32_t ahc_debug = AHC_DEBUG_OPTS;
2073 #endif
2074
2075 #if 0
2076 static void
2077 ahc_print_scb(struct scb *scb)
2078 {
2079 int i;
2080
2081 struct hardware_scb *hscb = scb->hscb;
2082
2083 printk("scb:%p control:0x%x scsiid:0x%x lun:%d cdb_len:%d\n",
2084 (void *)scb,
2085 hscb->control,
2086 hscb->scsiid,
2087 hscb->lun,
2088 hscb->cdb_len);
2089 printk("Shared Data: ");
2090 for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
2091 printk("%#02x", hscb->shared_data.cdb[i]);
2092 printk(" dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
2093 ahc_le32toh(hscb->dataptr),
2094 ahc_le32toh(hscb->datacnt),
2095 ahc_le32toh(hscb->sgptr),
2096 hscb->tag);
2097 if (scb->sg_count > 0) {
2098 for (i = 0; i < scb->sg_count; i++) {
2099 printk("sg[%d] - Addr 0x%x%x : Length %d\n",
2100 i,
2101 (ahc_le32toh(scb->sg_list[i].len) >> 24
2102 & SG_HIGH_ADDR_BITS),
2103 ahc_le32toh(scb->sg_list[i].addr),
2104 ahc_le32toh(scb->sg_list[i].len));
2105 }
2106 }
2107 }
2108 #endif
2109
2110
2111
2112
2113
2114
2115 static struct ahc_tmode_tstate *
2116 ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel)
2117 {
2118 struct ahc_tmode_tstate *master_tstate;
2119 struct ahc_tmode_tstate *tstate;
2120 int i;
2121
2122 master_tstate = ahc->enabled_targets[ahc->our_id];
2123 if (channel == 'B') {
2124 scsi_id += 8;
2125 master_tstate = ahc->enabled_targets[ahc->our_id_b + 8];
2126 }
2127 if (ahc->enabled_targets[scsi_id] != NULL
2128 && ahc->enabled_targets[scsi_id] != master_tstate)
2129 panic("%s: ahc_alloc_tstate - Target already allocated",
2130 ahc_name(ahc));
2131 tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC);
2132 if (tstate == NULL)
2133 return (NULL);
2134
2135
2136
2137
2138
2139
2140
2141 if (master_tstate != NULL) {
2142 memcpy(tstate, master_tstate, sizeof(*tstate));
2143 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
2144 tstate->ultraenb = 0;
2145 for (i = 0; i < AHC_NUM_TARGETS; i++) {
2146 memset(&tstate->transinfo[i].curr, 0,
2147 sizeof(tstate->transinfo[i].curr));
2148 memset(&tstate->transinfo[i].goal, 0,
2149 sizeof(tstate->transinfo[i].goal));
2150 }
2151 } else
2152 memset(tstate, 0, sizeof(*tstate));
2153 ahc->enabled_targets[scsi_id] = tstate;
2154 return (tstate);
2155 }
2156
2157 #ifdef AHC_TARGET_MODE
2158
2159
2160
2161
2162 static void
2163 ahc_free_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel, int force)
2164 {
2165 struct ahc_tmode_tstate *tstate;
2166
2167
2168
2169
2170
2171 if (((channel == 'B' && scsi_id == ahc->our_id_b)
2172 || (channel == 'A' && scsi_id == ahc->our_id))
2173 && force == FALSE)
2174 return;
2175
2176 if (channel == 'B')
2177 scsi_id += 8;
2178 tstate = ahc->enabled_targets[scsi_id];
2179 kfree(tstate);
2180 ahc->enabled_targets[scsi_id] = NULL;
2181 }
2182 #endif
2183
2184
2185
2186
2187
2188
2189
2190 static const struct ahc_syncrate *
2191 ahc_devlimited_syncrate(struct ahc_softc *ahc,
2192 struct ahc_initiator_tinfo *tinfo,
2193 u_int *period, u_int *ppr_options, role_t role)
2194 {
2195 struct ahc_transinfo *transinfo;
2196 u_int maxsync;
2197
2198 if ((ahc->features & AHC_ULTRA2) != 0) {
2199 if ((ahc_inb(ahc, SBLKCTL) & ENAB40) != 0
2200 && (ahc_inb(ahc, SSTAT2) & EXP_ACTIVE) == 0) {
2201 maxsync = AHC_SYNCRATE_DT;
2202 } else {
2203 maxsync = AHC_SYNCRATE_ULTRA;
2204
2205 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2206 }
2207 } else if ((ahc->features & AHC_ULTRA) != 0) {
2208 maxsync = AHC_SYNCRATE_ULTRA;
2209 } else {
2210 maxsync = AHC_SYNCRATE_FAST;
2211 }
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222 if (role == ROLE_TARGET)
2223 transinfo = &tinfo->user;
2224 else
2225 transinfo = &tinfo->goal;
2226 *ppr_options &= transinfo->ppr_options;
2227 if (transinfo->width == MSG_EXT_WDTR_BUS_8_BIT) {
2228 maxsync = max(maxsync, (u_int)AHC_SYNCRATE_ULTRA2);
2229 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2230 }
2231 if (transinfo->period == 0) {
2232 *period = 0;
2233 *ppr_options = 0;
2234 return (NULL);
2235 }
2236 *period = max(*period, (u_int)transinfo->period);
2237 return (ahc_find_syncrate(ahc, period, ppr_options, maxsync));
2238 }
2239
2240
2241
2242
2243
2244
2245 const struct ahc_syncrate *
2246 ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
2247 u_int *ppr_options, u_int maxsync)
2248 {
2249 const struct ahc_syncrate *syncrate;
2250
2251 if ((ahc->features & AHC_DT) == 0)
2252 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2253
2254
2255 if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
2256 && maxsync < AHC_SYNCRATE_ULTRA2)
2257 maxsync = AHC_SYNCRATE_ULTRA2;
2258
2259
2260
2261 if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
2262 && maxsync < AHC_SYNCRATE_ULTRA)
2263 maxsync = AHC_SYNCRATE_ULTRA;
2264 if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
2265 && maxsync < AHC_SYNCRATE_FAST)
2266 maxsync = AHC_SYNCRATE_FAST;
2267
2268 for (syncrate = &ahc_syncrates[maxsync];
2269 syncrate->rate != NULL;
2270 syncrate++) {
2271
2272
2273
2274
2275
2276 if ((ahc->features & AHC_ULTRA2) != 0
2277 && (syncrate->sxfr_u2 == 0))
2278 break;
2279
2280 if (*period <= syncrate->period) {
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292 if (syncrate == &ahc_syncrates[maxsync])
2293 *period = syncrate->period;
2294
2295
2296
2297
2298
2299 if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
2300 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2301 break;
2302 }
2303 }
2304
2305 if ((*period == 0)
2306 || (syncrate->rate == NULL)
2307 || ((ahc->features & AHC_ULTRA2) != 0
2308 && (syncrate->sxfr_u2 == 0))) {
2309
2310 *period = 0;
2311 syncrate = NULL;
2312 *ppr_options &= ~MSG_EXT_PPR_DT_REQ;
2313 }
2314 return (syncrate);
2315 }
2316
2317
2318
2319
2320
2321 u_int
2322 ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync)
2323 {
2324 const struct ahc_syncrate *syncrate;
2325
2326 if ((ahc->features & AHC_ULTRA2) != 0)
2327 scsirate &= SXFR_ULTRA2;
2328 else
2329 scsirate &= SXFR;
2330
2331
2332 if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2)
2333 maxsync = AHC_SYNCRATE_ULTRA2;
2334 if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
2335 && maxsync < AHC_SYNCRATE_ULTRA)
2336 maxsync = AHC_SYNCRATE_ULTRA;
2337 if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
2338 && maxsync < AHC_SYNCRATE_FAST)
2339 maxsync = AHC_SYNCRATE_FAST;
2340
2341
2342 syncrate = &ahc_syncrates[maxsync];
2343 while (syncrate->rate != NULL) {
2344
2345 if ((ahc->features & AHC_ULTRA2) != 0) {
2346 if (syncrate->sxfr_u2 == 0)
2347 break;
2348 else if (scsirate == (syncrate->sxfr_u2 & SXFR_ULTRA2))
2349 return (syncrate->period);
2350 } else if (scsirate == (syncrate->sxfr & SXFR)) {
2351 return (syncrate->period);
2352 }
2353 syncrate++;
2354 }
2355 return (0);
2356 }
2357
2358
2359
2360
2361
2362 static void
2363 ahc_validate_offset(struct ahc_softc *ahc,
2364 struct ahc_initiator_tinfo *tinfo,
2365 const struct ahc_syncrate *syncrate,
2366 u_int *offset, int wide, role_t role)
2367 {
2368 u_int maxoffset;
2369
2370
2371 if (syncrate == NULL) {
2372 maxoffset = 0;
2373 } else if ((ahc->features & AHC_ULTRA2) != 0) {
2374 maxoffset = MAX_OFFSET_ULTRA2;
2375 } else {
2376 if (wide)
2377 maxoffset = MAX_OFFSET_16BIT;
2378 else
2379 maxoffset = MAX_OFFSET_8BIT;
2380 }
2381 *offset = min(*offset, maxoffset);
2382 if (tinfo != NULL) {
2383 if (role == ROLE_TARGET)
2384 *offset = min(*offset, (u_int)tinfo->user.offset);
2385 else
2386 *offset = min(*offset, (u_int)tinfo->goal.offset);
2387 }
2388 }
2389
2390
2391
2392
2393
2394 static void
2395 ahc_validate_width(struct ahc_softc *ahc, struct ahc_initiator_tinfo *tinfo,
2396 u_int *bus_width, role_t role)
2397 {
2398 switch (*bus_width) {
2399 default:
2400 if (ahc->features & AHC_WIDE) {
2401
2402 *bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2403 break;
2404 }
2405 fallthrough;
2406 case MSG_EXT_WDTR_BUS_8_BIT:
2407 *bus_width = MSG_EXT_WDTR_BUS_8_BIT;
2408 break;
2409 }
2410 if (tinfo != NULL) {
2411 if (role == ROLE_TARGET)
2412 *bus_width = min((u_int)tinfo->user.width, *bus_width);
2413 else
2414 *bus_width = min((u_int)tinfo->goal.width, *bus_width);
2415 }
2416 }
2417
2418
2419
2420
2421
2422
2423
2424 int
2425 ahc_update_neg_request(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2426 struct ahc_tmode_tstate *tstate,
2427 struct ahc_initiator_tinfo *tinfo, ahc_neg_type neg_type)
2428 {
2429 u_int auto_negotiate_orig;
2430
2431 auto_negotiate_orig = tstate->auto_negotiate;
2432 if (neg_type == AHC_NEG_ALWAYS) {
2433
2434
2435
2436
2437
2438
2439 if ((ahc->features & AHC_WIDE) != 0)
2440 tinfo->curr.width = AHC_WIDTH_UNKNOWN;
2441 tinfo->curr.period = AHC_PERIOD_UNKNOWN;
2442 tinfo->curr.offset = AHC_OFFSET_UNKNOWN;
2443 }
2444 if (tinfo->curr.period != tinfo->goal.period
2445 || tinfo->curr.width != tinfo->goal.width
2446 || tinfo->curr.offset != tinfo->goal.offset
2447 || tinfo->curr.ppr_options != tinfo->goal.ppr_options
2448 || (neg_type == AHC_NEG_IF_NON_ASYNC
2449 && (tinfo->goal.offset != 0
2450 || tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT
2451 || tinfo->goal.ppr_options != 0)))
2452 tstate->auto_negotiate |= devinfo->target_mask;
2453 else
2454 tstate->auto_negotiate &= ~devinfo->target_mask;
2455
2456 return (auto_negotiate_orig != tstate->auto_negotiate);
2457 }
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467 void
2468 ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2469 const struct ahc_syncrate *syncrate, u_int period,
2470 u_int offset, u_int ppr_options, u_int type, int paused)
2471 {
2472 struct ahc_initiator_tinfo *tinfo;
2473 struct ahc_tmode_tstate *tstate;
2474 u_int old_period;
2475 u_int old_offset;
2476 u_int old_ppr;
2477 int active;
2478 int update_needed;
2479
2480 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
2481 update_needed = 0;
2482
2483 if (syncrate == NULL) {
2484 period = 0;
2485 offset = 0;
2486 }
2487
2488 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2489 devinfo->target, &tstate);
2490
2491 if ((type & AHC_TRANS_USER) != 0) {
2492 tinfo->user.period = period;
2493 tinfo->user.offset = offset;
2494 tinfo->user.ppr_options = ppr_options;
2495 }
2496
2497 if ((type & AHC_TRANS_GOAL) != 0) {
2498 tinfo->goal.period = period;
2499 tinfo->goal.offset = offset;
2500 tinfo->goal.ppr_options = ppr_options;
2501 }
2502
2503 old_period = tinfo->curr.period;
2504 old_offset = tinfo->curr.offset;
2505 old_ppr = tinfo->curr.ppr_options;
2506
2507 if ((type & AHC_TRANS_CUR) != 0
2508 && (old_period != period
2509 || old_offset != offset
2510 || old_ppr != ppr_options)) {
2511 u_int scsirate;
2512
2513 update_needed++;
2514 scsirate = tinfo->scsirate;
2515 if ((ahc->features & AHC_ULTRA2) != 0) {
2516
2517 scsirate &= ~(SXFR_ULTRA2|SINGLE_EDGE|ENABLE_CRC);
2518 if (syncrate != NULL) {
2519 scsirate |= syncrate->sxfr_u2;
2520 if ((ppr_options & MSG_EXT_PPR_DT_REQ) != 0)
2521 scsirate |= ENABLE_CRC;
2522 else
2523 scsirate |= SINGLE_EDGE;
2524 }
2525 } else {
2526
2527 scsirate &= ~(SXFR|SOFS);
2528
2529
2530
2531
2532 tstate->ultraenb &= ~devinfo->target_mask;
2533 if (syncrate != NULL) {
2534 if (syncrate->sxfr & ULTRA_SXFR) {
2535 tstate->ultraenb |=
2536 devinfo->target_mask;
2537 }
2538 scsirate |= syncrate->sxfr & SXFR;
2539 scsirate |= offset & SOFS;
2540 }
2541 if (active) {
2542 u_int sxfrctl0;
2543
2544 sxfrctl0 = ahc_inb(ahc, SXFRCTL0);
2545 sxfrctl0 &= ~FAST20;
2546 if (tstate->ultraenb & devinfo->target_mask)
2547 sxfrctl0 |= FAST20;
2548 ahc_outb(ahc, SXFRCTL0, sxfrctl0);
2549 }
2550 }
2551 if (active) {
2552 ahc_outb(ahc, SCSIRATE, scsirate);
2553 if ((ahc->features & AHC_ULTRA2) != 0)
2554 ahc_outb(ahc, SCSIOFFSET, offset);
2555 }
2556
2557 tinfo->scsirate = scsirate;
2558 tinfo->curr.period = period;
2559 tinfo->curr.offset = offset;
2560 tinfo->curr.ppr_options = ppr_options;
2561
2562 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2563 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
2564 if (bootverbose) {
2565 if (offset != 0) {
2566 printk("%s: target %d synchronous at %sMHz%s, "
2567 "offset = 0x%x\n", ahc_name(ahc),
2568 devinfo->target, syncrate->rate,
2569 (ppr_options & MSG_EXT_PPR_DT_REQ)
2570 ? " DT" : "", offset);
2571 } else {
2572 printk("%s: target %d using "
2573 "asynchronous transfers\n",
2574 ahc_name(ahc), devinfo->target);
2575 }
2576 }
2577 }
2578
2579 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2580 tinfo, AHC_NEG_TO_GOAL);
2581
2582 if (update_needed)
2583 ahc_update_pending_scbs(ahc);
2584 }
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594 void
2595 ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2596 u_int width, u_int type, int paused)
2597 {
2598 struct ahc_initiator_tinfo *tinfo;
2599 struct ahc_tmode_tstate *tstate;
2600 u_int oldwidth;
2601 int active;
2602 int update_needed;
2603
2604 active = (type & AHC_TRANS_ACTIVE) == AHC_TRANS_ACTIVE;
2605 update_needed = 0;
2606 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2607 devinfo->target, &tstate);
2608
2609 if ((type & AHC_TRANS_USER) != 0)
2610 tinfo->user.width = width;
2611
2612 if ((type & AHC_TRANS_GOAL) != 0)
2613 tinfo->goal.width = width;
2614
2615 oldwidth = tinfo->curr.width;
2616 if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) {
2617 u_int scsirate;
2618
2619 update_needed++;
2620 scsirate = tinfo->scsirate;
2621 scsirate &= ~WIDEXFER;
2622 if (width == MSG_EXT_WDTR_BUS_16_BIT)
2623 scsirate |= WIDEXFER;
2624
2625 tinfo->scsirate = scsirate;
2626
2627 if (active)
2628 ahc_outb(ahc, SCSIRATE, scsirate);
2629
2630 tinfo->curr.width = width;
2631
2632 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2633 CAM_LUN_WILDCARD, AC_TRANSFER_NEG);
2634 if (bootverbose) {
2635 printk("%s: target %d using %dbit transfers\n",
2636 ahc_name(ahc), devinfo->target,
2637 8 * (0x01 << width));
2638 }
2639 }
2640
2641 update_needed += ahc_update_neg_request(ahc, devinfo, tstate,
2642 tinfo, AHC_NEG_TO_GOAL);
2643 if (update_needed)
2644 ahc_update_pending_scbs(ahc);
2645 }
2646
2647
2648
2649
2650 static void
2651 ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
2652 struct ahc_devinfo *devinfo, ahc_queue_alg alg)
2653 {
2654 struct scsi_device *sdev = cmd->device;
2655
2656 ahc_platform_set_tags(ahc, sdev, devinfo, alg);
2657 ahc_send_async(ahc, devinfo->channel, devinfo->target,
2658 devinfo->lun, AC_TRANSFER_NEG);
2659 }
2660
2661
2662
2663
2664
2665
2666 static void
2667 ahc_update_pending_scbs(struct ahc_softc *ahc)
2668 {
2669 struct scb *pending_scb;
2670 int pending_scb_count;
2671 int i;
2672 int paused;
2673 u_int saved_scbptr;
2674
2675
2676
2677
2678
2679 pending_scb_count = 0;
2680 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2681 struct ahc_devinfo devinfo;
2682 struct hardware_scb *pending_hscb;
2683 struct ahc_initiator_tinfo *tinfo;
2684 struct ahc_tmode_tstate *tstate;
2685
2686 ahc_scb_devinfo(ahc, &devinfo, pending_scb);
2687 tinfo = ahc_fetch_transinfo(ahc, devinfo.channel,
2688 devinfo.our_scsiid,
2689 devinfo.target, &tstate);
2690 pending_hscb = pending_scb->hscb;
2691 pending_hscb->control &= ~ULTRAENB;
2692 if ((tstate->ultraenb & devinfo.target_mask) != 0)
2693 pending_hscb->control |= ULTRAENB;
2694 pending_hscb->scsirate = tinfo->scsirate;
2695 pending_hscb->scsioffset = tinfo->curr.offset;
2696 if ((tstate->auto_negotiate & devinfo.target_mask) == 0
2697 && (pending_scb->flags & SCB_AUTO_NEGOTIATE) != 0) {
2698 pending_scb->flags &= ~SCB_AUTO_NEGOTIATE;
2699 pending_hscb->control &= ~MK_MESSAGE;
2700 }
2701 ahc_sync_scb(ahc, pending_scb,
2702 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2703 pending_scb_count++;
2704 }
2705
2706 if (pending_scb_count == 0)
2707 return;
2708
2709 if (ahc_is_paused(ahc)) {
2710 paused = 1;
2711 } else {
2712 paused = 0;
2713 ahc_pause(ahc);
2714 }
2715
2716 saved_scbptr = ahc_inb(ahc, SCBPTR);
2717
2718 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
2719 struct hardware_scb *pending_hscb;
2720 u_int control;
2721 u_int scb_tag;
2722
2723 ahc_outb(ahc, SCBPTR, i);
2724 scb_tag = ahc_inb(ahc, SCB_TAG);
2725 pending_scb = ahc_lookup_scb(ahc, scb_tag);
2726 if (pending_scb == NULL)
2727 continue;
2728
2729 pending_hscb = pending_scb->hscb;
2730 control = ahc_inb(ahc, SCB_CONTROL);
2731 control &= ~(ULTRAENB|MK_MESSAGE);
2732 control |= pending_hscb->control & (ULTRAENB|MK_MESSAGE);
2733 ahc_outb(ahc, SCB_CONTROL, control);
2734 ahc_outb(ahc, SCB_SCSIRATE, pending_hscb->scsirate);
2735 ahc_outb(ahc, SCB_SCSIOFFSET, pending_hscb->scsioffset);
2736 }
2737 ahc_outb(ahc, SCBPTR, saved_scbptr);
2738
2739 if (paused == 0)
2740 ahc_unpause(ahc);
2741 }
2742
2743
2744 static void
2745 ahc_fetch_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2746 {
2747 u_int saved_scsiid;
2748 role_t role;
2749 int our_id;
2750
2751 if (ahc_inb(ahc, SSTAT0) & TARGET)
2752 role = ROLE_TARGET;
2753 else
2754 role = ROLE_INITIATOR;
2755
2756 if (role == ROLE_TARGET
2757 && (ahc->features & AHC_MULTI_TID) != 0
2758 && (ahc_inb(ahc, SEQ_FLAGS)
2759 & (CMDPHASE_PENDING|TARG_CMD_PENDING|NO_DISCONNECT)) != 0) {
2760
2761 our_id = ahc_inb(ahc, TARGIDIN) & OID;
2762 } else if ((ahc->features & AHC_ULTRA2) != 0)
2763 our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID;
2764 else
2765 our_id = ahc_inb(ahc, SCSIID) & OID;
2766
2767 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2768 ahc_compile_devinfo(devinfo,
2769 our_id,
2770 SCSIID_TARGET(ahc, saved_scsiid),
2771 ahc_inb(ahc, SAVED_LUN),
2772 SCSIID_CHANNEL(ahc, saved_scsiid),
2773 role);
2774 }
2775
2776 static const struct ahc_phase_table_entry*
2777 ahc_lookup_phase_entry(int phase)
2778 {
2779 const struct ahc_phase_table_entry *entry;
2780 const struct ahc_phase_table_entry *last_entry;
2781
2782
2783
2784
2785
2786 last_entry = &ahc_phase_table[num_phases];
2787 for (entry = ahc_phase_table; entry < last_entry; entry++) {
2788 if (phase == entry->phase)
2789 break;
2790 }
2791 return (entry);
2792 }
2793
2794 void
2795 ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target,
2796 u_int lun, char channel, role_t role)
2797 {
2798 devinfo->our_scsiid = our_id;
2799 devinfo->target = target;
2800 devinfo->lun = lun;
2801 devinfo->target_offset = target;
2802 devinfo->channel = channel;
2803 devinfo->role = role;
2804 if (channel == 'B')
2805 devinfo->target_offset += 8;
2806 devinfo->target_mask = (0x01 << devinfo->target_offset);
2807 }
2808
2809 void
2810 ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2811 {
2812 printk("%s:%c:%d:%d: ", ahc_name(ahc), devinfo->channel,
2813 devinfo->target, devinfo->lun);
2814 }
2815
2816 static void
2817 ahc_scb_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2818 struct scb *scb)
2819 {
2820 role_t role;
2821 int our_id;
2822
2823 our_id = SCSIID_OUR_ID(scb->hscb->scsiid);
2824 role = ROLE_INITIATOR;
2825 if ((scb->flags & SCB_TARGET_SCB) != 0)
2826 role = ROLE_TARGET;
2827 ahc_compile_devinfo(devinfo, our_id, SCB_GET_TARGET(ahc, scb),
2828 SCB_GET_LUN(scb), SCB_GET_CHANNEL(ahc, scb), role);
2829 }
2830
2831
2832
2833 static void
2834 ahc_assert_atn(struct ahc_softc *ahc)
2835 {
2836 u_int scsisigo;
2837
2838 scsisigo = ATNO;
2839 if ((ahc->features & AHC_DT) == 0)
2840 scsisigo |= ahc_inb(ahc, SCSISIGI);
2841 ahc_outb(ahc, SCSISIGO, scsisigo);
2842 }
2843
2844
2845
2846
2847
2848
2849
2850 static void
2851 ahc_setup_initiator_msgout(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
2852 struct scb *scb)
2853 {
2854
2855
2856
2857
2858
2859 ahc->msgout_index = 0;
2860 ahc->msgout_len = 0;
2861
2862 if ((scb->flags & SCB_DEVICE_RESET) == 0
2863 && ahc_inb(ahc, MSG_OUT) == MSG_IDENTIFYFLAG) {
2864 u_int identify_msg;
2865
2866 identify_msg = MSG_IDENTIFYFLAG | SCB_GET_LUN(scb);
2867 if ((scb->hscb->control & DISCENB) != 0)
2868 identify_msg |= MSG_IDENTIFY_DISCFLAG;
2869 ahc->msgout_buf[ahc->msgout_index++] = identify_msg;
2870 ahc->msgout_len++;
2871
2872 if ((scb->hscb->control & TAG_ENB) != 0) {
2873 ahc->msgout_buf[ahc->msgout_index++] =
2874 scb->hscb->control & (TAG_ENB|SCB_TAG_TYPE);
2875 ahc->msgout_buf[ahc->msgout_index++] = scb->hscb->tag;
2876 ahc->msgout_len += 2;
2877 }
2878 }
2879
2880 if (scb->flags & SCB_DEVICE_RESET) {
2881 ahc->msgout_buf[ahc->msgout_index++] = TARGET_RESET;
2882 ahc->msgout_len++;
2883 ahc_print_path(ahc, scb);
2884 printk("Bus Device Reset Message Sent\n");
2885
2886
2887
2888
2889
2890
2891
2892 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2893 } else if ((scb->flags & SCB_ABORT) != 0) {
2894 if ((scb->hscb->control & TAG_ENB) != 0)
2895 ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK;
2896 else
2897 ahc->msgout_buf[ahc->msgout_index++] = ABORT_TASK_SET;
2898 ahc->msgout_len++;
2899 ahc_print_path(ahc, scb);
2900 printk("Abort%s Message Sent\n",
2901 (scb->hscb->control & TAG_ENB) != 0 ? " Tag" : "");
2902
2903
2904
2905
2906
2907
2908
2909 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
2910 } else if ((scb->flags & (SCB_AUTO_NEGOTIATE|SCB_NEGOTIATE)) != 0) {
2911 ahc_build_transfer_msg(ahc, devinfo);
2912 } else {
2913 printk("ahc_intr: AWAITING_MSG for an SCB that "
2914 "does not have a waiting message\n");
2915 printk("SCSIID = %x, target_mask = %x\n", scb->hscb->scsiid,
2916 devinfo->target_mask);
2917 panic("SCB = %d, SCB Control = %x, MSG_OUT = %x "
2918 "SCB flags = %x", scb->hscb->tag, scb->hscb->control,
2919 ahc_inb(ahc, MSG_OUT), scb->flags);
2920 }
2921
2922
2923
2924
2925
2926 ahc_outb(ahc, SCB_CONTROL, ahc_inb(ahc, SCB_CONTROL) & ~MK_MESSAGE);
2927 scb->hscb->control &= ~MK_MESSAGE;
2928 ahc->msgout_index = 0;
2929 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
2930 }
2931
2932
2933
2934
2935
2936 static void
2937 ahc_build_transfer_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
2938 {
2939
2940
2941
2942
2943
2944 struct ahc_initiator_tinfo *tinfo;
2945 struct ahc_tmode_tstate *tstate;
2946 const struct ahc_syncrate *rate;
2947 int dowide;
2948 int dosync;
2949 int doppr;
2950 u_int period;
2951 u_int ppr_options;
2952 u_int offset;
2953
2954 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
2955 devinfo->target, &tstate);
2956
2957
2958
2959
2960
2961
2962 period = tinfo->goal.period;
2963 offset = tinfo->goal.offset;
2964 ppr_options = tinfo->goal.ppr_options;
2965
2966 if (devinfo->role == ROLE_TARGET)
2967 ppr_options = 0;
2968 rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
2969 &ppr_options, devinfo->role);
2970 dowide = tinfo->curr.width != tinfo->goal.width;
2971 dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
2972
2973
2974
2975
2976
2977 doppr = ppr_options != 0;
2978
2979 if (!dowide && !dosync && !doppr) {
2980 dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
2981 dosync = tinfo->goal.offset != 0;
2982 }
2983
2984 if (!dowide && !dosync && !doppr) {
2985
2986
2987
2988
2989 if ((ahc->features & AHC_WIDE) != 0)
2990 dowide = 1;
2991 else
2992 dosync = 1;
2993
2994 if (bootverbose) {
2995 ahc_print_devinfo(ahc, devinfo);
2996 printk("Ensuring async\n");
2997 }
2998 }
2999
3000
3001 if (devinfo->role == ROLE_TARGET)
3002 doppr = 0;
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012 if (doppr || (dosync && !dowide)) {
3013
3014 offset = tinfo->goal.offset;
3015 ahc_validate_offset(ahc, tinfo, rate, &offset,
3016 doppr ? tinfo->goal.width
3017 : tinfo->curr.width,
3018 devinfo->role);
3019 if (doppr) {
3020 ahc_construct_ppr(ahc, devinfo, period, offset,
3021 tinfo->goal.width, ppr_options);
3022 } else {
3023 ahc_construct_sdtr(ahc, devinfo, period, offset);
3024 }
3025 } else {
3026 ahc_construct_wdtr(ahc, devinfo, tinfo->goal.width);
3027 }
3028 }
3029
3030
3031
3032
3033
3034 static void
3035 ahc_construct_sdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3036 u_int period, u_int offset)
3037 {
3038 if (offset == 0)
3039 period = AHC_ASYNC_XFER_PERIOD;
3040 ahc->msgout_index += spi_populate_sync_msg(
3041 ahc->msgout_buf + ahc->msgout_index, period, offset);
3042 ahc->msgout_len += 5;
3043 if (bootverbose) {
3044 printk("(%s:%c:%d:%d): Sending SDTR period %x, offset %x\n",
3045 ahc_name(ahc), devinfo->channel, devinfo->target,
3046 devinfo->lun, period, offset);
3047 }
3048 }
3049
3050
3051
3052
3053
3054 static void
3055 ahc_construct_wdtr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3056 u_int bus_width)
3057 {
3058 ahc->msgout_index += spi_populate_width_msg(
3059 ahc->msgout_buf + ahc->msgout_index, bus_width);
3060 ahc->msgout_len += 4;
3061 if (bootverbose) {
3062 printk("(%s:%c:%d:%d): Sending WDTR %x\n",
3063 ahc_name(ahc), devinfo->channel, devinfo->target,
3064 devinfo->lun, bus_width);
3065 }
3066 }
3067
3068
3069
3070
3071
3072 static void
3073 ahc_construct_ppr(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
3074 u_int period, u_int offset, u_int bus_width,
3075 u_int ppr_options)
3076 {
3077 if (offset == 0)
3078 period = AHC_ASYNC_XFER_PERIOD;
3079 ahc->msgout_index += spi_populate_ppr_msg(
3080 ahc->msgout_buf + ahc->msgout_index, period, offset,
3081 bus_width, ppr_options);
3082 ahc->msgout_len += 8;
3083 if (bootverbose) {
3084 printk("(%s:%c:%d:%d): Sending PPR bus_width %x, period %x, "
3085 "offset %x, ppr_options %x\n", ahc_name(ahc),
3086 devinfo->channel, devinfo->target, devinfo->lun,
3087 bus_width, period, offset, ppr_options);
3088 }
3089 }
3090
3091
3092
3093
3094 static void
3095 ahc_clear_msg_state(struct ahc_softc *ahc)
3096 {
3097 ahc->msgout_len = 0;
3098 ahc->msgin_index = 0;
3099 ahc->msg_type = MSG_TYPE_NONE;
3100 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0) {
3101
3102
3103
3104
3105 ahc_outb(ahc, CLRSINT1, CLRATNO);
3106 }
3107 ahc_outb(ahc, MSG_OUT, NOP);
3108 ahc_outb(ahc, SEQ_FLAGS2,
3109 ahc_inb(ahc, SEQ_FLAGS2) & ~TARGET_MSG_PENDING);
3110 }
3111
3112 static void
3113 ahc_handle_proto_violation(struct ahc_softc *ahc)
3114 {
3115 struct ahc_devinfo devinfo;
3116 struct scb *scb;
3117 u_int scbid;
3118 u_int seq_flags;
3119 u_int curphase;
3120 u_int lastphase;
3121 int found;
3122
3123 ahc_fetch_devinfo(ahc, &devinfo);
3124 scbid = ahc_inb(ahc, SCB_TAG);
3125 scb = ahc_lookup_scb(ahc, scbid);
3126 seq_flags = ahc_inb(ahc, SEQ_FLAGS);
3127 curphase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
3128 lastphase = ahc_inb(ahc, LASTPHASE);
3129 if ((seq_flags & NOT_IDENTIFIED) != 0) {
3130
3131
3132
3133
3134
3135
3136 ahc_print_devinfo(ahc, &devinfo);
3137 printk("Target did not send an IDENTIFY message. "
3138 "LASTPHASE = 0x%x.\n", lastphase);
3139 scb = NULL;
3140 } else if (scb == NULL) {
3141
3142
3143
3144
3145 ahc_print_devinfo(ahc, &devinfo);
3146 printk("No SCB found during protocol violation\n");
3147 goto proto_violation_reset;
3148 } else {
3149 ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
3150 if ((seq_flags & NO_CDB_SENT) != 0) {
3151 ahc_print_path(ahc, scb);
3152 printk("No or incomplete CDB sent to device.\n");
3153 } else if ((ahc_inb(ahc, SCB_CONTROL) & STATUS_RCVD) == 0) {
3154
3155
3156
3157
3158
3159
3160
3161 ahc_print_path(ahc, scb);
3162 printk("Completed command without status.\n");
3163 } else {
3164 ahc_print_path(ahc, scb);
3165 printk("Unknown protocol violation.\n");
3166 ahc_dump_card_state(ahc);
3167 }
3168 }
3169 if ((lastphase & ~P_DATAIN_DT) == 0
3170 || lastphase == P_COMMAND) {
3171 proto_violation_reset:
3172
3173
3174
3175
3176
3177
3178 found = ahc_reset_channel(ahc, 'A', TRUE);
3179 printk("%s: Issued Channel %c Bus Reset. "
3180 "%d SCBs aborted\n", ahc_name(ahc), 'A', found);
3181 } else {
3182
3183
3184
3185
3186
3187 ahc_outb(ahc, SCSISEQ,
3188 ahc_inb(ahc, SCSISEQ) & ~ENSELO);
3189 ahc_assert_atn(ahc);
3190 ahc_outb(ahc, MSG_OUT, HOST_MSG);
3191 if (scb == NULL) {
3192 ahc_print_devinfo(ahc, &devinfo);
3193 ahc->msgout_buf[0] = ABORT_TASK;
3194 ahc->msgout_len = 1;
3195 ahc->msgout_index = 0;
3196 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3197 } else {
3198 ahc_print_path(ahc, scb);
3199 scb->flags |= SCB_ABORT;
3200 }
3201 printk("Protocol violation %s. Attempting to abort.\n",
3202 ahc_lookup_phase_entry(curphase)->phasemsg);
3203 }
3204 }
3205
3206
3207
3208
3209 static void
3210 ahc_handle_message_phase(struct ahc_softc *ahc)
3211 {
3212 struct ahc_devinfo devinfo;
3213 u_int bus_phase;
3214 int end_session;
3215
3216 ahc_fetch_devinfo(ahc, &devinfo);
3217 end_session = FALSE;
3218 bus_phase = ahc_inb(ahc, SCSISIGI) & PHASE_MASK;
3219
3220 reswitch:
3221 switch (ahc->msg_type) {
3222 case MSG_TYPE_INITIATOR_MSGOUT:
3223 {
3224 int lastbyte;
3225 int phasemis;
3226 int msgdone;
3227
3228 if (ahc->msgout_len == 0)
3229 panic("HOST_MSG_LOOP interrupt with no active message");
3230
3231 #ifdef AHC_DEBUG
3232 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
3233 ahc_print_devinfo(ahc, &devinfo);
3234 printk("INITIATOR_MSG_OUT");
3235 }
3236 #endif
3237 phasemis = bus_phase != P_MESGOUT;
3238 if (phasemis) {
3239 #ifdef AHC_DEBUG
3240 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
3241 printk(" PHASEMIS %s\n",
3242 ahc_lookup_phase_entry(bus_phase)
3243 ->phasemsg);
3244 }
3245 #endif
3246 if (bus_phase == P_MESGIN) {
3247
3248
3249
3250
3251
3252
3253 ahc_outb(ahc, CLRSINT1, CLRATNO);
3254 ahc->send_msg_perror = FALSE;
3255 ahc->msg_type = MSG_TYPE_INITIATOR_MSGIN;
3256 ahc->msgin_index = 0;
3257 goto reswitch;
3258 }
3259 end_session = TRUE;
3260 break;
3261 }
3262
3263 if (ahc->send_msg_perror) {
3264 ahc_outb(ahc, CLRSINT1, CLRATNO);
3265 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
3266 #ifdef AHC_DEBUG
3267 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
3268 printk(" byte 0x%x\n", ahc->send_msg_perror);
3269 #endif
3270 ahc_outb(ahc, SCSIDATL, MSG_PARITY_ERROR);
3271 break;
3272 }
3273
3274 msgdone = ahc->msgout_index == ahc->msgout_len;
3275 if (msgdone) {
3276
3277
3278
3279
3280
3281 ahc->msgout_index = 0;
3282 ahc_assert_atn(ahc);
3283 }
3284
3285 lastbyte = ahc->msgout_index == (ahc->msgout_len - 1);
3286 if (lastbyte) {
3287
3288 ahc_outb(ahc, CLRSINT1, CLRATNO);
3289 }
3290
3291
3292
3293
3294
3295 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
3296 #ifdef AHC_DEBUG
3297 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
3298 printk(" byte 0x%x\n",
3299 ahc->msgout_buf[ahc->msgout_index]);
3300 #endif
3301 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
3302 break;
3303 }
3304 case MSG_TYPE_INITIATOR_MSGIN:
3305 {
3306 int phasemis;
3307 int message_done;
3308
3309 #ifdef AHC_DEBUG
3310 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
3311 ahc_print_devinfo(ahc, &devinfo);
3312 printk("INITIATOR_MSG_IN");
3313 }
3314 #endif
3315 phasemis = bus_phase != P_MESGIN;
3316 if (phasemis) {
3317 #ifdef AHC_DEBUG
3318 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
3319 printk(" PHASEMIS %s\n",
3320 ahc_lookup_phase_entry(bus_phase)
3321 ->phasemsg);
3322 }
3323 #endif
3324 ahc->msgin_index = 0;
3325 if (bus_phase == P_MESGOUT
3326 && (ahc->send_msg_perror == TRUE
3327 || (ahc->msgout_len != 0
3328 && ahc->msgout_index == 0))) {
3329 ahc->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
3330 goto reswitch;
3331 }
3332 end_session = TRUE;
3333 break;
3334 }
3335
3336
3337 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIBUSL);
3338 #ifdef AHC_DEBUG
3339 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
3340 printk(" byte 0x%x\n",
3341 ahc->msgin_buf[ahc->msgin_index]);
3342 #endif
3343
3344 message_done = ahc_parse_msg(ahc, &devinfo);
3345
3346 if (message_done) {
3347
3348
3349
3350
3351 ahc->msgin_index = 0;
3352
3353
3354
3355
3356
3357
3358 if (ahc->msgout_len != 0) {
3359 #ifdef AHC_DEBUG
3360 if ((ahc_debug & AHC_SHOW_MESSAGES) != 0) {
3361 ahc_print_devinfo(ahc, &devinfo);
3362 printk("Asserting ATN for response\n");
3363 }
3364 #endif
3365 ahc_assert_atn(ahc);
3366 }
3367 } else
3368 ahc->msgin_index++;
3369
3370 if (message_done == MSGLOOP_TERMINATED) {
3371 end_session = TRUE;
3372 } else {
3373
3374 ahc_outb(ahc, CLRSINT1, CLRREQINIT);
3375 ahc_inb(ahc, SCSIDATL);
3376 }
3377 break;
3378 }
3379 case MSG_TYPE_TARGET_MSGIN:
3380 {
3381 int msgdone;
3382 int msgout_request;
3383
3384 if (ahc->msgout_len == 0)
3385 panic("Target MSGIN with no active message");
3386
3387
3388
3389
3390
3391
3392
3393 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0
3394 && ahc->msgout_index > 0)
3395 msgout_request = TRUE;
3396 else
3397 msgout_request = FALSE;
3398
3399 if (msgout_request) {
3400
3401
3402
3403
3404
3405
3406
3407 ahc->msg_type = MSG_TYPE_TARGET_MSGOUT;
3408 ahc_outb(ahc, SCSISIGO, P_MESGOUT | BSYO);
3409 ahc->msgin_index = 0;
3410
3411 ahc_inb(ahc, SCSIDATL);
3412 ahc_outb(ahc, SXFRCTL0,
3413 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
3414 break;
3415 }
3416
3417 msgdone = ahc->msgout_index == ahc->msgout_len;
3418 if (msgdone) {
3419 ahc_outb(ahc, SXFRCTL0,
3420 ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
3421 end_session = TRUE;
3422 break;
3423 }
3424
3425
3426
3427
3428 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) | SPIOEN);
3429 ahc_outb(ahc, SCSIDATL, ahc->msgout_buf[ahc->msgout_index++]);
3430 break;
3431 }
3432 case MSG_TYPE_TARGET_MSGOUT:
3433 {
3434 int lastbyte;
3435 int msgdone;
3436
3437
3438
3439
3440
3441 lastbyte = (ahc_inb(ahc, SCSISIGI) & ATNI) == 0;
3442
3443
3444
3445
3446
3447
3448 ahc_outb(ahc, SXFRCTL0, ahc_inb(ahc, SXFRCTL0) & ~SPIOEN);
3449 ahc->msgin_buf[ahc->msgin_index] = ahc_inb(ahc, SCSIDATL);
3450 msgdone = ahc_parse_msg(ahc, &devinfo);
3451 if (msgdone == MSGLOOP_TERMINATED) {
3452
3453
3454
3455
3456
3457
3458 return;
3459 }
3460
3461 ahc->msgin_index++;
3462
3463
3464
3465
3466
3467 if (msgdone == MSGLOOP_MSGCOMPLETE) {
3468 ahc->msgin_index = 0;
3469
3470
3471
3472
3473
3474 if (ahc->msgout_len != 0) {
3475 ahc_outb(ahc, SCSISIGO, P_MESGIN | BSYO);
3476 ahc_outb(ahc, SXFRCTL0,
3477 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
3478 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
3479 ahc->msgin_index = 0;
3480 break;
3481 }
3482 }
3483
3484 if (lastbyte)
3485 end_session = TRUE;
3486 else {
3487
3488 ahc_outb(ahc, SXFRCTL0,
3489 ahc_inb(ahc, SXFRCTL0) | SPIOEN);
3490 }
3491
3492 break;
3493 }
3494 default:
3495 panic("Unknown REQINIT message type");
3496 }
3497
3498 if (end_session) {
3499 ahc_clear_msg_state(ahc);
3500 ahc_outb(ahc, RETURN_1, EXIT_MSG_LOOP);
3501 } else
3502 ahc_outb(ahc, RETURN_1, CONT_MSG_LOOP);
3503 }
3504
3505
3506
3507
3508
3509
3510
3511 static int
3512 ahc_sent_msg(struct ahc_softc *ahc, ahc_msgtype type, u_int msgval, int full)
3513 {
3514 int found;
3515 u_int index;
3516
3517 found = FALSE;
3518 index = 0;
3519
3520 while (index < ahc->msgout_len) {
3521 if (ahc->msgout_buf[index] == EXTENDED_MESSAGE) {
3522 u_int end_index;
3523
3524 end_index = index + 1 + ahc->msgout_buf[index + 1];
3525 if (ahc->msgout_buf[index+2] == msgval
3526 && type == AHCMSG_EXT) {
3527
3528 if (full) {
3529 if (ahc->msgout_index > end_index)
3530 found = TRUE;
3531 } else if (ahc->msgout_index > index)
3532 found = TRUE;
3533 }
3534 index = end_index;
3535 } else if (ahc->msgout_buf[index] >= SIMPLE_QUEUE_TAG
3536 && ahc->msgout_buf[index] <= IGNORE_WIDE_RESIDUE) {
3537
3538
3539 index += 2;
3540 } else {
3541
3542 if (type == AHCMSG_1B
3543 && ahc->msgout_buf[index] == msgval
3544 && ahc->msgout_index > index)
3545 found = TRUE;
3546 index++;
3547 }
3548
3549 if (found)
3550 break;
3551 }
3552 return (found);
3553 }
3554
3555
3556
3557
3558 static int
3559 ahc_parse_msg(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3560 {
3561 struct ahc_initiator_tinfo *tinfo;
3562 struct ahc_tmode_tstate *tstate;
3563 int reject;
3564 int done;
3565 int response;
3566 u_int targ_scsirate;
3567
3568 done = MSGLOOP_IN_PROG;
3569 response = FALSE;
3570 reject = FALSE;
3571 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
3572 devinfo->target, &tstate);
3573 targ_scsirate = tinfo->scsirate;
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586 switch (ahc->msgin_buf[0]) {
3587 case DISCONNECT:
3588 case SAVE_POINTERS:
3589 case COMMAND_COMPLETE:
3590 case RESTORE_POINTERS:
3591 case IGNORE_WIDE_RESIDUE:
3592
3593
3594
3595
3596 done = MSGLOOP_TERMINATED;
3597 break;
3598 case MESSAGE_REJECT:
3599 response = ahc_handle_msg_reject(ahc, devinfo);
3600 fallthrough;
3601 case NOP:
3602 done = MSGLOOP_MSGCOMPLETE;
3603 break;
3604 case EXTENDED_MESSAGE:
3605 {
3606
3607 if (ahc->msgin_index < 2)
3608 break;
3609 switch (ahc->msgin_buf[2]) {
3610 case EXTENDED_SDTR:
3611 {
3612 const struct ahc_syncrate *syncrate;
3613 u_int period;
3614 u_int ppr_options;
3615 u_int offset;
3616 u_int saved_offset;
3617
3618 if (ahc->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
3619 reject = TRUE;
3620 break;
3621 }
3622
3623
3624
3625
3626
3627
3628
3629
3630 if (ahc->msgin_index < (MSG_EXT_SDTR_LEN + 1))
3631 break;
3632
3633 period = ahc->msgin_buf[3];
3634 ppr_options = 0;
3635 saved_offset = offset = ahc->msgin_buf[4];
3636 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3637 &ppr_options,
3638 devinfo->role);
3639 ahc_validate_offset(ahc, tinfo, syncrate, &offset,
3640 targ_scsirate & WIDEXFER,
3641 devinfo->role);
3642 if (bootverbose) {
3643 printk("(%s:%c:%d:%d): Received "
3644 "SDTR period %x, offset %x\n\t"
3645 "Filtered to period %x, offset %x\n",
3646 ahc_name(ahc), devinfo->channel,
3647 devinfo->target, devinfo->lun,
3648 ahc->msgin_buf[3], saved_offset,
3649 period, offset);
3650 }
3651 ahc_set_syncrate(ahc, devinfo,
3652 syncrate, period,
3653 offset, ppr_options,
3654 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3655 TRUE);
3656
3657
3658
3659
3660
3661
3662 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, TRUE)) {
3663
3664 if (saved_offset != offset) {
3665
3666 reject = TRUE;
3667 }
3668 } else {
3669
3670
3671
3672 if (bootverbose
3673 && devinfo->role == ROLE_INITIATOR) {
3674 printk("(%s:%c:%d:%d): Target "
3675 "Initiated SDTR\n",
3676 ahc_name(ahc), devinfo->channel,
3677 devinfo->target, devinfo->lun);
3678 }
3679 ahc->msgout_index = 0;
3680 ahc->msgout_len = 0;
3681 ahc_construct_sdtr(ahc, devinfo,
3682 period, offset);
3683 ahc->msgout_index = 0;
3684 response = TRUE;
3685 }
3686 done = MSGLOOP_MSGCOMPLETE;
3687 break;
3688 }
3689 case EXTENDED_WDTR:
3690 {
3691 u_int bus_width;
3692 u_int saved_width;
3693 u_int sending_reply;
3694
3695 sending_reply = FALSE;
3696 if (ahc->msgin_buf[1] != MSG_EXT_WDTR_LEN) {
3697 reject = TRUE;
3698 break;
3699 }
3700
3701
3702
3703
3704
3705
3706
3707
3708 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1))
3709 break;
3710
3711 bus_width = ahc->msgin_buf[3];
3712 saved_width = bus_width;
3713 ahc_validate_width(ahc, tinfo, &bus_width,
3714 devinfo->role);
3715 if (bootverbose) {
3716 printk("(%s:%c:%d:%d): Received WDTR "
3717 "%x filtered to %x\n",
3718 ahc_name(ahc), devinfo->channel,
3719 devinfo->target, devinfo->lun,
3720 saved_width, bus_width);
3721 }
3722
3723 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, TRUE)) {
3724
3725
3726
3727
3728
3729
3730 if (saved_width > bus_width) {
3731 reject = TRUE;
3732 printk("(%s:%c:%d:%d): requested %dBit "
3733 "transfers. Rejecting...\n",
3734 ahc_name(ahc), devinfo->channel,
3735 devinfo->target, devinfo->lun,
3736 8 * (0x01 << bus_width));
3737 bus_width = 0;
3738 }
3739 } else {
3740
3741
3742
3743 if (bootverbose
3744 && devinfo->role == ROLE_INITIATOR) {
3745 printk("(%s:%c:%d:%d): Target "
3746 "Initiated WDTR\n",
3747 ahc_name(ahc), devinfo->channel,
3748 devinfo->target, devinfo->lun);
3749 }
3750 ahc->msgout_index = 0;
3751 ahc->msgout_len = 0;
3752 ahc_construct_wdtr(ahc, devinfo, bus_width);
3753 ahc->msgout_index = 0;
3754 response = TRUE;
3755 sending_reply = TRUE;
3756 }
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766 ahc_update_neg_request(ahc, devinfo, tstate,
3767 tinfo, AHC_NEG_ALWAYS);
3768 ahc_set_width(ahc, devinfo, bus_width,
3769 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3770 TRUE);
3771 if (sending_reply == FALSE && reject == FALSE) {
3772
3773
3774
3775
3776 ahc->msgout_index = 0;
3777 ahc->msgout_len = 0;
3778 ahc_build_transfer_msg(ahc, devinfo);
3779 ahc->msgout_index = 0;
3780 response = TRUE;
3781 }
3782 done = MSGLOOP_MSGCOMPLETE;
3783 break;
3784 }
3785 case EXTENDED_PPR:
3786 {
3787 const struct ahc_syncrate *syncrate;
3788 u_int period;
3789 u_int offset;
3790 u_int bus_width;
3791 u_int ppr_options;
3792 u_int saved_width;
3793 u_int saved_offset;
3794 u_int saved_ppr_options;
3795
3796 if (ahc->msgin_buf[1] != MSG_EXT_PPR_LEN) {
3797 reject = TRUE;
3798 break;
3799 }
3800
3801
3802
3803
3804
3805
3806
3807
3808 if (ahc->msgin_index < (MSG_EXT_PPR_LEN + 1))
3809 break;
3810
3811 period = ahc->msgin_buf[3];
3812 offset = ahc->msgin_buf[5];
3813 bus_width = ahc->msgin_buf[6];
3814 saved_width = bus_width;
3815 ppr_options = ahc->msgin_buf[7];
3816
3817
3818
3819
3820
3821 if ((ppr_options & MSG_EXT_PPR_DT_REQ) == 0
3822 && period == 9)
3823 offset = 0;
3824 saved_ppr_options = ppr_options;
3825 saved_offset = offset;
3826
3827
3828
3829
3830
3831
3832 ppr_options &= MSG_EXT_PPR_DT_REQ;
3833 if (bus_width == 0)
3834 ppr_options = 0;
3835
3836 ahc_validate_width(ahc, tinfo, &bus_width,
3837 devinfo->role);
3838 syncrate = ahc_devlimited_syncrate(ahc, tinfo, &period,
3839 &ppr_options,
3840 devinfo->role);
3841 ahc_validate_offset(ahc, tinfo, syncrate,
3842 &offset, bus_width,
3843 devinfo->role);
3844
3845 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, TRUE)) {
3846
3847
3848
3849
3850
3851 if (saved_width > bus_width
3852 || saved_offset != offset
3853 || saved_ppr_options != ppr_options) {
3854 reject = TRUE;
3855 period = 0;
3856 offset = 0;
3857 bus_width = 0;
3858 ppr_options = 0;
3859 syncrate = NULL;
3860 }
3861 } else {
3862 if (devinfo->role != ROLE_TARGET)
3863 printk("(%s:%c:%d:%d): Target "
3864 "Initiated PPR\n",
3865 ahc_name(ahc), devinfo->channel,
3866 devinfo->target, devinfo->lun);
3867 else
3868 printk("(%s:%c:%d:%d): Initiator "
3869 "Initiated PPR\n",
3870 ahc_name(ahc), devinfo->channel,
3871 devinfo->target, devinfo->lun);
3872 ahc->msgout_index = 0;
3873 ahc->msgout_len = 0;
3874 ahc_construct_ppr(ahc, devinfo, period, offset,
3875 bus_width, ppr_options);
3876 ahc->msgout_index = 0;
3877 response = TRUE;
3878 }
3879 if (bootverbose) {
3880 printk("(%s:%c:%d:%d): Received PPR width %x, "
3881 "period %x, offset %x,options %x\n"
3882 "\tFiltered to width %x, period %x, "
3883 "offset %x, options %x\n",
3884 ahc_name(ahc), devinfo->channel,
3885 devinfo->target, devinfo->lun,
3886 saved_width, ahc->msgin_buf[3],
3887 saved_offset, saved_ppr_options,
3888 bus_width, period, offset, ppr_options);
3889 }
3890 ahc_set_width(ahc, devinfo, bus_width,
3891 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3892 TRUE);
3893 ahc_set_syncrate(ahc, devinfo,
3894 syncrate, period,
3895 offset, ppr_options,
3896 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
3897 TRUE);
3898 done = MSGLOOP_MSGCOMPLETE;
3899 break;
3900 }
3901 default:
3902
3903 reject = TRUE;
3904 break;
3905 }
3906 break;
3907 }
3908 #ifdef AHC_TARGET_MODE
3909 case TARGET_RESET:
3910 ahc_handle_devreset(ahc, devinfo,
3911 CAM_BDR_SENT,
3912 "Bus Device Reset Received",
3913 0);
3914 ahc_restart(ahc);
3915 done = MSGLOOP_TERMINATED;
3916 break;
3917 case ABORT_TASK:
3918 case ABORT_TASK_SET:
3919 case CLEAR_QUEUE_TASK_SET:
3920 {
3921 int tag;
3922
3923
3924 if (devinfo->role != ROLE_TARGET) {
3925 reject = TRUE;
3926 break;
3927 }
3928 tag = SCB_LIST_NULL;
3929 if (ahc->msgin_buf[0] == ABORT_TASK)
3930 tag = ahc_inb(ahc, INITIATOR_TAG);
3931 ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
3932 devinfo->lun, tag, ROLE_TARGET,
3933 CAM_REQ_ABORTED);
3934
3935 tstate = ahc->enabled_targets[devinfo->our_scsiid];
3936 if (tstate != NULL) {
3937 struct ahc_tmode_lstate* lstate;
3938
3939 lstate = tstate->enabled_luns[devinfo->lun];
3940 if (lstate != NULL) {
3941 ahc_queue_lstate_event(ahc, lstate,
3942 devinfo->our_scsiid,
3943 ahc->msgin_buf[0],
3944 tag);
3945 ahc_send_lstate_events(ahc, lstate);
3946 }
3947 }
3948 ahc_restart(ahc);
3949 done = MSGLOOP_TERMINATED;
3950 break;
3951 }
3952 #endif
3953 case TERMINATE_IO_PROC:
3954 default:
3955 reject = TRUE;
3956 break;
3957 }
3958
3959 if (reject) {
3960
3961
3962
3963 ahc->msgout_index = 0;
3964 ahc->msgout_len = 1;
3965 ahc->msgout_buf[0] = MESSAGE_REJECT;
3966 done = MSGLOOP_MSGCOMPLETE;
3967 response = TRUE;
3968 }
3969
3970 if (done != MSGLOOP_IN_PROG && !response)
3971
3972 ahc->msgout_len = 0;
3973
3974 return (done);
3975 }
3976
3977
3978
3979
3980 static int
3981 ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
3982 {
3983
3984
3985
3986
3987
3988
3989 struct scb *scb;
3990 struct ahc_initiator_tinfo *tinfo;
3991 struct ahc_tmode_tstate *tstate;
3992 u_int scb_index;
3993 u_int last_msg;
3994 int response = 0;
3995
3996 scb_index = ahc_inb(ahc, SCB_TAG);
3997 scb = ahc_lookup_scb(ahc, scb_index);
3998 tinfo = ahc_fetch_transinfo(ahc, devinfo->channel,
3999 devinfo->our_scsiid,
4000 devinfo->target, &tstate);
4001
4002 last_msg = ahc_inb(ahc, LAST_MSG);
4003
4004 if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_PPR, FALSE)) {
4005
4006
4007
4008
4009 if (bootverbose) {
4010 printk("(%s:%c:%d:%d): PPR Rejected. "
4011 "Trying WDTR/SDTR\n",
4012 ahc_name(ahc), devinfo->channel,
4013 devinfo->target, devinfo->lun);
4014 }
4015 tinfo->goal.ppr_options = 0;
4016 tinfo->curr.transport_version = 2;
4017 tinfo->goal.transport_version = 2;
4018 ahc->msgout_index = 0;
4019 ahc->msgout_len = 0;
4020 ahc_build_transfer_msg(ahc, devinfo);
4021 ahc->msgout_index = 0;
4022 response = 1;
4023 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_WDTR, FALSE)) {
4024
4025
4026 printk("(%s:%c:%d:%d): refuses WIDE negotiation. Using "
4027 "8bit transfers\n", ahc_name(ahc),
4028 devinfo->channel, devinfo->target, devinfo->lun);
4029 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4030 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
4031 TRUE);
4032
4033
4034
4035
4036
4037
4038
4039 if (tinfo->goal.offset != tinfo->curr.offset) {
4040
4041
4042 ahc->msgout_index = 0;
4043 ahc->msgout_len = 0;
4044 ahc_build_transfer_msg(ahc, devinfo);
4045 ahc->msgout_index = 0;
4046 response = 1;
4047 }
4048 } else if (ahc_sent_msg(ahc, AHCMSG_EXT, EXTENDED_SDTR, FALSE)) {
4049
4050 ahc_set_syncrate(ahc, devinfo, NULL, 0,
4051 0, 0,
4052 AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
4053 TRUE);
4054 printk("(%s:%c:%d:%d): refuses synchronous negotiation. "
4055 "Using asynchronous transfers\n",
4056 ahc_name(ahc), devinfo->channel,
4057 devinfo->target, devinfo->lun);
4058 } else if ((scb->hscb->control & SIMPLE_QUEUE_TAG) != 0) {
4059 int tag_type;
4060 int mask;
4061
4062 tag_type = (scb->hscb->control & SIMPLE_QUEUE_TAG);
4063
4064 if (tag_type == SIMPLE_QUEUE_TAG) {
4065 printk("(%s:%c:%d:%d): refuses tagged commands. "
4066 "Performing non-tagged I/O\n", ahc_name(ahc),
4067 devinfo->channel, devinfo->target, devinfo->lun);
4068 ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_NONE);
4069 mask = ~0x23;
4070 } else {
4071 printk("(%s:%c:%d:%d): refuses %s tagged commands. "
4072 "Performing simple queue tagged I/O only\n",
4073 ahc_name(ahc), devinfo->channel, devinfo->target,
4074 devinfo->lun, tag_type == ORDERED_QUEUE_TAG
4075 ? "ordered" : "head of queue");
4076 ahc_set_tags(ahc, scb->io_ctx, devinfo, AHC_QUEUE_BASIC);
4077 mask = ~0x03;
4078 }
4079
4080
4081
4082
4083
4084 ahc_outb(ahc, SCB_CONTROL,
4085 ahc_inb(ahc, SCB_CONTROL) & mask);
4086 scb->hscb->control &= mask;
4087 ahc_set_transaction_tag(scb, FALSE,
4088 SIMPLE_QUEUE_TAG);
4089 ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
4090 ahc_assert_atn(ahc);
4091
4092
4093
4094
4095
4096 if ((ahc->flags & AHC_SCB_BTT) == 0) {
4097 struct scb_tailq *untagged_q;
4098
4099 untagged_q =
4100 &(ahc->untagged_queues[devinfo->target_offset]);
4101 TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe);
4102 scb->flags |= SCB_UNTAGGEDQ;
4103 }
4104 ahc_busy_tcl(ahc, BUILD_TCL(scb->hscb->scsiid, devinfo->lun),
4105 scb->hscb->tag);
4106
4107
4108
4109
4110
4111
4112 ahc_search_qinfifo(ahc, SCB_GET_TARGET(ahc, scb),
4113 SCB_GET_CHANNEL(ahc, scb),
4114 SCB_GET_LUN(scb), SCB_LIST_NULL,
4115 ROLE_INITIATOR, CAM_REQUEUE_REQ,
4116 SEARCH_COMPLETE);
4117 } else {
4118
4119
4120
4121 printk("%s:%c:%d: Message reject for %x -- ignored\n",
4122 ahc_name(ahc), devinfo->channel, devinfo->target,
4123 last_msg);
4124 }
4125 return (response);
4126 }
4127
4128
4129
4130
4131 static void
4132 ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
4133 {
4134 u_int scb_index;
4135 struct scb *scb;
4136
4137 scb_index = ahc_inb(ahc, SCB_TAG);
4138 scb = ahc_lookup_scb(ahc, scb_index);
4139
4140
4141
4142
4143 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
4144 || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
4145
4146
4147
4148
4149 } else {
4150
4151
4152
4153
4154
4155
4156
4157 uint32_t sgptr;
4158
4159 sgptr = ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
4160 if ((sgptr & SG_LIST_NULL) != 0
4161 && (ahc_inb(ahc, SCB_LUN) & SCB_XFERLEN_ODD) != 0) {
4162
4163
4164
4165
4166
4167
4168 } else {
4169 struct ahc_dma_seg *sg;
4170 uint32_t data_cnt;
4171 uint32_t data_addr;
4172 uint32_t sglen;
4173
4174
4175 sgptr = ahc_inl(ahc, SCB_RESIDUAL_SGPTR);
4176 data_cnt = ahc_inl(ahc, SCB_RESIDUAL_DATACNT);
4177
4178 if ((sgptr & SG_LIST_NULL) != 0) {
4179
4180
4181
4182
4183
4184 data_cnt &= ~AHC_SG_LEN_MASK;
4185 }
4186
4187 data_addr = ahc_inl(ahc, SHADDR);
4188
4189 data_cnt += 1;
4190 data_addr -= 1;
4191 sgptr &= SG_PTR_MASK;
4192
4193 sg = ahc_sg_bus_to_virt(scb, sgptr);
4194
4195
4196
4197
4198
4199 sg--;
4200 sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
4201 if (sg != scb->sg_list
4202 && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
4203
4204 sg--;
4205 sglen = ahc_le32toh(sg->len);
4206
4207
4208
4209
4210 data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
4211 data_addr = ahc_le32toh(sg->addr)
4212 + (sglen & AHC_SG_LEN_MASK) - 1;
4213
4214
4215
4216
4217
4218 sg++;
4219 sgptr = ahc_sg_virt_to_bus(scb, sg);
4220 }
4221 ahc_outl(ahc, SCB_RESIDUAL_SGPTR, sgptr);
4222 ahc_outl(ahc, SCB_RESIDUAL_DATACNT, data_cnt);
4223
4224
4225
4226
4227
4228
4229 ahc_outb(ahc, SCB_LUN,
4230 ahc_inb(ahc, SCB_LUN) ^ SCB_XFERLEN_ODD);
4231 }
4232 }
4233 }
4234
4235
4236
4237
4238
4239
4240 static void
4241 ahc_reinitialize_dataptrs(struct ahc_softc *ahc)
4242 {
4243 struct scb *scb;
4244 struct ahc_dma_seg *sg;
4245 u_int scb_index;
4246 uint32_t sgptr;
4247 uint32_t resid;
4248 uint32_t dataptr;
4249
4250 scb_index = ahc_inb(ahc, SCB_TAG);
4251 scb = ahc_lookup_scb(ahc, scb_index);
4252 sgptr = (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 3) << 24)
4253 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 2) << 16)
4254 | (ahc_inb(ahc, SCB_RESIDUAL_SGPTR + 1) << 8)
4255 | ahc_inb(ahc, SCB_RESIDUAL_SGPTR);
4256
4257 sgptr &= SG_PTR_MASK;
4258 sg = ahc_sg_bus_to_virt(scb, sgptr);
4259
4260
4261 sg--;
4262
4263 resid = (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 2) << 16)
4264 | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
4265 | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
4266
4267 dataptr = ahc_le32toh(sg->addr)
4268 + (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
4269 - resid;
4270 if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
4271 u_int dscommand1;
4272
4273 dscommand1 = ahc_inb(ahc, DSCOMMAND1);
4274 ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
4275 ahc_outb(ahc, HADDR,
4276 (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
4277 ahc_outb(ahc, DSCOMMAND1, dscommand1);
4278 }
4279 ahc_outb(ahc, HADDR + 3, dataptr >> 24);
4280 ahc_outb(ahc, HADDR + 2, dataptr >> 16);
4281 ahc_outb(ahc, HADDR + 1, dataptr >> 8);
4282 ahc_outb(ahc, HADDR, dataptr);
4283 ahc_outb(ahc, HCNT + 2, resid >> 16);
4284 ahc_outb(ahc, HCNT + 1, resid >> 8);
4285 ahc_outb(ahc, HCNT, resid);
4286 if ((ahc->features & AHC_ULTRA2) == 0) {
4287 ahc_outb(ahc, STCNT + 2, resid >> 16);
4288 ahc_outb(ahc, STCNT + 1, resid >> 8);
4289 ahc_outb(ahc, STCNT, resid);
4290 }
4291 }
4292
4293
4294
4295
4296 static void
4297 ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
4298 cam_status status, char *message, int verbose_level)
4299 {
4300 #ifdef AHC_TARGET_MODE
4301 struct ahc_tmode_tstate* tstate;
4302 u_int lun;
4303 #endif
4304 int found;
4305
4306 found = ahc_abort_scbs(ahc, devinfo->target, devinfo->channel,
4307 CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role,
4308 status);
4309
4310 #ifdef AHC_TARGET_MODE
4311
4312
4313
4314
4315 tstate = ahc->enabled_targets[devinfo->our_scsiid];
4316 if (tstate != NULL) {
4317 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
4318 struct ahc_tmode_lstate* lstate;
4319
4320 lstate = tstate->enabled_luns[lun];
4321 if (lstate == NULL)
4322 continue;
4323
4324 ahc_queue_lstate_event(ahc, lstate, devinfo->our_scsiid,
4325 TARGET_RESET, 0);
4326 ahc_send_lstate_events(ahc, lstate);
4327 }
4328 }
4329 #endif
4330
4331
4332
4333
4334 ahc_set_width(ahc, devinfo, MSG_EXT_WDTR_BUS_8_BIT,
4335 AHC_TRANS_CUR, TRUE);
4336 ahc_set_syncrate(ahc, devinfo, NULL,
4337 0, 0, 0,
4338 AHC_TRANS_CUR, TRUE);
4339
4340 if (status != CAM_SEL_TIMEOUT)
4341 ahc_send_async(ahc, devinfo->channel, devinfo->target,
4342 CAM_LUN_WILDCARD, AC_SENT_BDR);
4343
4344 if (message != NULL
4345 && (verbose_level <= bootverbose))
4346 printk("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
4347 message, devinfo->channel, devinfo->target, found);
4348 }
4349
4350 #ifdef AHC_TARGET_MODE
4351 static void
4352 ahc_setup_target_msgin(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
4353 struct scb *scb)
4354 {
4355
4356
4357
4358
4359
4360
4361 ahc->msgout_index = 0;
4362 ahc->msgout_len = 0;
4363
4364 if (scb != NULL && (scb->flags & SCB_AUTO_NEGOTIATE) != 0)
4365 ahc_build_transfer_msg(ahc, devinfo);
4366 else
4367 panic("ahc_intr: AWAITING target message with no message");
4368
4369 ahc->msgout_index = 0;
4370 ahc->msg_type = MSG_TYPE_TARGET_MSGIN;
4371 }
4372 #endif
4373
4374
4375
4376
4377
4378 struct ahc_softc *
4379 ahc_alloc(void *platform_arg, char *name)
4380 {
4381 struct ahc_softc *ahc;
4382 int i;
4383
4384 ahc = kzalloc(sizeof(*ahc), GFP_ATOMIC);
4385 if (!ahc) {
4386 printk("aic7xxx: cannot malloc softc!\n");
4387 kfree(name);
4388 return NULL;
4389 }
4390
4391 ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC);
4392 if (ahc->seep_config == NULL) {
4393 kfree(ahc);
4394 kfree(name);
4395 return (NULL);
4396 }
4397 LIST_INIT(&ahc->pending_scbs);
4398
4399 ahc->name = name;
4400 ahc->unit = -1;
4401 ahc->description = NULL;
4402 ahc->channel = 'A';
4403 ahc->channel_b = 'B';
4404 ahc->chip = AHC_NONE;
4405 ahc->features = AHC_FENONE;
4406 ahc->bugs = AHC_BUGNONE;
4407 ahc->flags = AHC_FNONE;
4408
4409
4410
4411
4412
4413 ahc->seqctl = FASTMODE;
4414
4415 for (i = 0; i < AHC_NUM_TARGETS; i++)
4416 TAILQ_INIT(&ahc->untagged_queues[i]);
4417 if (ahc_platform_alloc(ahc, platform_arg) != 0) {
4418 ahc_free(ahc);
4419 ahc = NULL;
4420 }
4421 return (ahc);
4422 }
4423
4424 int
4425 ahc_softc_init(struct ahc_softc *ahc)
4426 {
4427
4428
4429 if ((ahc->chip & AHC_PCI) == 0)
4430 ahc->unpause = ahc_inb(ahc, HCNTRL) & IRQMS;
4431 else
4432 ahc->unpause = 0;
4433 ahc->pause = ahc->unpause | PAUSE;
4434
4435 if (ahc->scb_data == NULL) {
4436 ahc->scb_data = kzalloc(sizeof(*ahc->scb_data), GFP_ATOMIC);
4437 if (ahc->scb_data == NULL)
4438 return (ENOMEM);
4439 }
4440
4441 return (0);
4442 }
4443
4444 void
4445 ahc_set_unit(struct ahc_softc *ahc, int unit)
4446 {
4447 ahc->unit = unit;
4448 }
4449
4450 void
4451 ahc_set_name(struct ahc_softc *ahc, char *name)
4452 {
4453 kfree(ahc->name);
4454 ahc->name = name;
4455 }
4456
4457 void
4458 ahc_free(struct ahc_softc *ahc)
4459 {
4460 int i;
4461
4462 switch (ahc->init_level) {
4463 default:
4464 case 5:
4465 ahc_shutdown(ahc);
4466 fallthrough;
4467 case 4:
4468 ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
4469 ahc->shared_data_dmamap);
4470 fallthrough;
4471 case 3:
4472 ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
4473 ahc->shared_data_dmamap);
4474 ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
4475 ahc->shared_data_dmamap);
4476 fallthrough;
4477 case 2:
4478 ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
4479 fallthrough;
4480 case 1:
4481 break;
4482 case 0:
4483 break;
4484 }
4485
4486 ahc_platform_free(ahc);
4487 ahc_fini_scbdata(ahc);
4488 for (i = 0; i < AHC_NUM_TARGETS; i++) {
4489 struct ahc_tmode_tstate *tstate;
4490
4491 tstate = ahc->enabled_targets[i];
4492 if (tstate != NULL) {
4493 #ifdef AHC_TARGET_MODE
4494 int j;
4495
4496 for (j = 0; j < AHC_NUM_LUNS; j++) {
4497 struct ahc_tmode_lstate *lstate;
4498
4499 lstate = tstate->enabled_luns[j];
4500 if (lstate != NULL) {
4501 xpt_free_path(lstate->path);
4502 kfree(lstate);
4503 }
4504 }
4505 #endif
4506 kfree(tstate);
4507 }
4508 }
4509 #ifdef AHC_TARGET_MODE
4510 if (ahc->black_hole != NULL) {
4511 xpt_free_path(ahc->black_hole->path);
4512 kfree(ahc->black_hole);
4513 }
4514 #endif
4515 kfree(ahc->name);
4516 kfree(ahc->seep_config);
4517 kfree(ahc);
4518 return;
4519 }
4520
4521 static void
4522 ahc_shutdown(void *arg)
4523 {
4524 struct ahc_softc *ahc;
4525 int i;
4526
4527 ahc = (struct ahc_softc *)arg;
4528
4529
4530 ahc_reset(ahc, FALSE);
4531 ahc_outb(ahc, SCSISEQ, 0);
4532 ahc_outb(ahc, SXFRCTL0, 0);
4533 ahc_outb(ahc, DSPCISTATUS, 0);
4534
4535 for (i = TARG_SCSIRATE; i < SCSICONF; i++)
4536 ahc_outb(ahc, i, 0);
4537 }
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548 int
4549 ahc_reset(struct ahc_softc *ahc, int reinit)
4550 {
4551 u_int sblkctl;
4552 u_int sxfrctl1_a, sxfrctl1_b;
4553 int error;
4554 int wait;
4555
4556
4557
4558
4559
4560
4561 ahc_pause(ahc);
4562 sxfrctl1_b = 0;
4563 if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
4564 u_int sblkctl;
4565
4566
4567
4568
4569
4570 sblkctl = ahc_inb(ahc, SBLKCTL);
4571 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4572 sxfrctl1_b = ahc_inb(ahc, SXFRCTL1);
4573 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4574 }
4575 sxfrctl1_a = ahc_inb(ahc, SXFRCTL1);
4576
4577 ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
4578
4579
4580
4581
4582
4583
4584
4585 wait = 1000;
4586 do {
4587 ahc_delay(1000);
4588 } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
4589
4590 if (wait == 0) {
4591 printk("%s: WARNING - Failed chip reset! "
4592 "Trying to initialize anyway.\n", ahc_name(ahc));
4593 }
4594 ahc_outb(ahc, HCNTRL, ahc->pause);
4595
4596
4597 sblkctl = ahc_inb(ahc, SBLKCTL) & (SELBUSB|SELWIDE);
4598
4599 if ((ahc->chip & AHC_PCI) != 0)
4600 sblkctl &= ~SELBUSB;
4601 switch (sblkctl) {
4602 case 0:
4603
4604 break;
4605 case 2:
4606
4607 ahc->features |= AHC_WIDE;
4608 break;
4609 case 8:
4610
4611 ahc->features |= AHC_TWIN;
4612 break;
4613 default:
4614 printk(" Unsupported adapter type. Ignoring\n");
4615 return(-1);
4616 }
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626 if ((ahc->features & AHC_TWIN) != 0) {
4627 u_int sblkctl;
4628
4629 sblkctl = ahc_inb(ahc, SBLKCTL);
4630 ahc_outb(ahc, SBLKCTL, sblkctl | SELBUSB);
4631 ahc_outb(ahc, SXFRCTL1, sxfrctl1_b);
4632 ahc_outb(ahc, SBLKCTL, sblkctl & ~SELBUSB);
4633 }
4634 ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
4635
4636 error = 0;
4637 if (reinit != 0)
4638
4639
4640
4641
4642 error = ahc->bus_chip_init(ahc);
4643 #ifdef AHC_DUMP_SEQ
4644 else
4645 ahc_dumpseq(ahc);
4646 #endif
4647
4648 return (error);
4649 }
4650
4651
4652
4653
4654 int
4655 ahc_probe_scbs(struct ahc_softc *ahc) {
4656 int i;
4657
4658 for (i = 0; i < AHC_SCB_MAX; i++) {
4659
4660 ahc_outb(ahc, SCBPTR, i);
4661 ahc_outb(ahc, SCB_BASE, i);
4662 if (ahc_inb(ahc, SCB_BASE) != i)
4663 break;
4664 ahc_outb(ahc, SCBPTR, 0);
4665 if (ahc_inb(ahc, SCB_BASE) != 0)
4666 break;
4667 }
4668 return (i);
4669 }
4670
4671 static void
4672 ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
4673 {
4674 dma_addr_t *baddr;
4675
4676 baddr = (dma_addr_t *)arg;
4677 *baddr = segs->ds_addr;
4678 }
4679
4680 static void
4681 ahc_build_free_scb_list(struct ahc_softc *ahc)
4682 {
4683 int scbsize;
4684 int i;
4685
4686 scbsize = 32;
4687 if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
4688 scbsize = 64;
4689
4690 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
4691 int j;
4692
4693 ahc_outb(ahc, SCBPTR, i);
4694
4695
4696
4697
4698
4699
4700 for (j = 0; j < scbsize; j++)
4701 ahc_outb(ahc, SCB_BASE+j, 0xFF);
4702
4703
4704 ahc_outb(ahc, SCB_CONTROL, 0);
4705
4706
4707 if ((ahc->flags & AHC_PAGESCBS) != 0)
4708 ahc_outb(ahc, SCB_NEXT, i+1);
4709 else
4710 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4711
4712
4713 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
4714 ahc_outb(ahc, SCB_SCSIID, 0xFF);
4715 ahc_outb(ahc, SCB_LUN, 0xFF);
4716 }
4717
4718 if ((ahc->flags & AHC_PAGESCBS) != 0) {
4719
4720 ahc_outb(ahc, FREE_SCBH, 0);
4721 } else {
4722
4723 ahc_outb(ahc, FREE_SCBH, SCB_LIST_NULL);
4724 }
4725
4726
4727 ahc_outb(ahc, SCBPTR, i-1);
4728 ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
4729 }
4730
4731 static int
4732 ahc_init_scbdata(struct ahc_softc *ahc)
4733 {
4734 struct scb_data *scb_data;
4735
4736 scb_data = ahc->scb_data;
4737 SLIST_INIT(&scb_data->free_scbs);
4738 SLIST_INIT(&scb_data->sg_maps);
4739
4740
4741 scb_data->scbarray = kcalloc(AHC_SCB_MAX_ALLOC, sizeof(struct scb),
4742 GFP_ATOMIC);
4743 if (scb_data->scbarray == NULL)
4744 return (ENOMEM);
4745
4746
4747
4748 scb_data->maxhscbs = ahc_probe_scbs(ahc);
4749 if (ahc->scb_data->maxhscbs == 0) {
4750 printk("%s: No SCB space found\n", ahc_name(ahc));
4751 return (ENXIO);
4752 }
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4766 BUS_SPACE_MAXADDR_32BIT + 1,
4767 BUS_SPACE_MAXADDR_32BIT,
4768 BUS_SPACE_MAXADDR,
4769 NULL, NULL,
4770 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4771 1,
4772 BUS_SPACE_MAXSIZE_32BIT,
4773 0, &scb_data->hscb_dmat) != 0) {
4774 goto error_exit;
4775 }
4776
4777 scb_data->init_level++;
4778
4779
4780 if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
4781 (void **)&scb_data->hscbs,
4782 BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
4783 goto error_exit;
4784 }
4785
4786 scb_data->init_level++;
4787
4788
4789 ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
4790 scb_data->hscbs,
4791 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
4792 ahc_dmamap_cb, &scb_data->hscb_busaddr, 0);
4793
4794 scb_data->init_level++;
4795
4796
4797 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
4798 BUS_SPACE_MAXADDR_32BIT + 1,
4799 BUS_SPACE_MAXADDR_32BIT,
4800 BUS_SPACE_MAXADDR,
4801 NULL, NULL,
4802 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4803 1,
4804 BUS_SPACE_MAXSIZE_32BIT,
4805 0, &scb_data->sense_dmat) != 0) {
4806 goto error_exit;
4807 }
4808
4809 scb_data->init_level++;
4810
4811
4812 if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
4813 (void **)&scb_data->sense,
4814 BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
4815 goto error_exit;
4816 }
4817
4818 scb_data->init_level++;
4819
4820
4821 ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
4822 scb_data->sense,
4823 AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
4824 ahc_dmamap_cb, &scb_data->sense_busaddr, 0);
4825
4826 scb_data->init_level++;
4827
4828
4829 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 8,
4830 BUS_SPACE_MAXADDR_32BIT + 1,
4831 BUS_SPACE_MAXADDR_32BIT,
4832 BUS_SPACE_MAXADDR,
4833 NULL, NULL,
4834 PAGE_SIZE, 1,
4835 BUS_SPACE_MAXSIZE_32BIT,
4836 0, &scb_data->sg_dmat) != 0) {
4837 goto error_exit;
4838 }
4839
4840 scb_data->init_level++;
4841
4842
4843 memset(scb_data->hscbs, 0,
4844 AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb));
4845 ahc_alloc_scbs(ahc);
4846
4847 if (scb_data->numscbs == 0) {
4848 printk("%s: ahc_init_scbdata - "
4849 "Unable to allocate initial scbs\n",
4850 ahc_name(ahc));
4851 goto error_exit;
4852 }
4853
4854
4855
4856
4857 ahc->next_queued_scb = ahc_get_scb(ahc);
4858
4859
4860
4861
4862 return (0);
4863
4864 error_exit:
4865
4866 return (ENOMEM);
4867 }
4868
4869 static void
4870 ahc_fini_scbdata(struct ahc_softc *ahc)
4871 {
4872 struct scb_data *scb_data;
4873
4874 scb_data = ahc->scb_data;
4875 if (scb_data == NULL)
4876 return;
4877
4878 switch (scb_data->init_level) {
4879 default:
4880 case 7:
4881 {
4882 struct sg_map_node *sg_map;
4883
4884 while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
4885 SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
4886 ahc_dmamap_unload(ahc, scb_data->sg_dmat,
4887 sg_map->sg_dmamap);
4888 ahc_dmamem_free(ahc, scb_data->sg_dmat,
4889 sg_map->sg_vaddr,
4890 sg_map->sg_dmamap);
4891 kfree(sg_map);
4892 }
4893 ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
4894 }
4895 fallthrough;
4896 case 6:
4897 ahc_dmamap_unload(ahc, scb_data->sense_dmat,
4898 scb_data->sense_dmamap);
4899 fallthrough;
4900 case 5:
4901 ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
4902 scb_data->sense_dmamap);
4903 ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
4904 scb_data->sense_dmamap);
4905 fallthrough;
4906 case 4:
4907 ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
4908 fallthrough;
4909 case 3:
4910 ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
4911 scb_data->hscb_dmamap);
4912 fallthrough;
4913 case 2:
4914 ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
4915 scb_data->hscb_dmamap);
4916 ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
4917 scb_data->hscb_dmamap);
4918 fallthrough;
4919 case 1:
4920 ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
4921 break;
4922 case 0:
4923 break;
4924 }
4925 kfree(scb_data->scbarray);
4926 }
4927
4928 static void
4929 ahc_alloc_scbs(struct ahc_softc *ahc)
4930 {
4931 struct scb_data *scb_data;
4932 struct scb *next_scb;
4933 struct sg_map_node *sg_map;
4934 dma_addr_t physaddr;
4935 struct ahc_dma_seg *segs;
4936 int newcount;
4937 int i;
4938
4939 scb_data = ahc->scb_data;
4940 if (scb_data->numscbs >= AHC_SCB_MAX_ALLOC)
4941
4942 return;
4943
4944 next_scb = &scb_data->scbarray[scb_data->numscbs];
4945
4946 sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC);
4947
4948 if (sg_map == NULL)
4949 return;
4950
4951
4952 if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
4953 (void **)&sg_map->sg_vaddr,
4954 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
4955 kfree(sg_map);
4956 return;
4957 }
4958
4959 SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
4960
4961 ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
4962 sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
4963 &sg_map->sg_physaddr, 0);
4964
4965 segs = sg_map->sg_vaddr;
4966 physaddr = sg_map->sg_physaddr;
4967
4968 newcount = (PAGE_SIZE / (AHC_NSEG * sizeof(struct ahc_dma_seg)));
4969 newcount = min(newcount, (AHC_SCB_MAX_ALLOC - scb_data->numscbs));
4970 for (i = 0; i < newcount; i++) {
4971 struct scb_platform_data *pdata;
4972
4973 pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC);
4974 if (pdata == NULL)
4975 break;
4976 next_scb->platform_data = pdata;
4977 next_scb->sg_map = sg_map;
4978 next_scb->sg_list = segs;
4979
4980
4981
4982
4983 next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
4984 next_scb->ahc_softc = ahc;
4985 next_scb->flags = SCB_FREE;
4986 next_scb->hscb = &scb_data->hscbs[scb_data->numscbs];
4987 next_scb->hscb->tag = ahc->scb_data->numscbs;
4988 SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs,
4989 next_scb, links.sle);
4990 segs += AHC_NSEG;
4991 physaddr += (AHC_NSEG * sizeof(struct ahc_dma_seg));
4992 next_scb++;
4993 ahc->scb_data->numscbs++;
4994 }
4995 }
4996
4997 void
4998 ahc_controller_info(struct ahc_softc *ahc, char *buf)
4999 {
5000 int len;
5001
5002 len = sprintf(buf, "%s: ", ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]);
5003 buf += len;
5004 if ((ahc->features & AHC_TWIN) != 0)
5005 len = sprintf(buf, "Twin Channel, A SCSI Id=%d, "
5006 "B SCSI Id=%d, primary %c, ",
5007 ahc->our_id, ahc->our_id_b,
5008 (ahc->flags & AHC_PRIMARY_CHANNEL) + 'A');
5009 else {
5010 const char *speed;
5011 const char *type;
5012
5013 speed = "";
5014 if ((ahc->features & AHC_ULTRA) != 0) {
5015 speed = "Ultra ";
5016 } else if ((ahc->features & AHC_DT) != 0) {
5017 speed = "Ultra160 ";
5018 } else if ((ahc->features & AHC_ULTRA2) != 0) {
5019 speed = "Ultra2 ";
5020 }
5021 if ((ahc->features & AHC_WIDE) != 0) {
5022 type = "Wide";
5023 } else {
5024 type = "Single";
5025 }
5026 len = sprintf(buf, "%s%s Channel %c, SCSI Id=%d, ",
5027 speed, type, ahc->channel, ahc->our_id);
5028 }
5029 buf += len;
5030
5031 if ((ahc->flags & AHC_PAGESCBS) != 0)
5032 sprintf(buf, "%d/%d SCBs",
5033 ahc->scb_data->maxhscbs, AHC_MAX_QUEUE);
5034 else
5035 sprintf(buf, "%d SCBs", ahc->scb_data->maxhscbs);
5036 }
5037
5038 int
5039 ahc_chip_init(struct ahc_softc *ahc)
5040 {
5041 int term;
5042 int error;
5043 u_int i;
5044 u_int scsi_conf;
5045 u_int scsiseq_template;
5046 uint32_t physaddr;
5047
5048 ahc_outb(ahc, SEQ_FLAGS, 0);
5049 ahc_outb(ahc, SEQ_FLAGS2, 0);
5050
5051
5052 if (ahc->features & AHC_TWIN) {
5053
5054
5055
5056
5057 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) | SELBUSB);
5058 term = (ahc->flags & AHC_TERM_ENB_B) != 0 ? STPWEN : 0;
5059 ahc_outb(ahc, SCSIID, ahc->our_id_b);
5060 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
5061 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
5062 |term|ahc->seltime_b|ENSTIMER|ACTNEGEN);
5063 if ((ahc->features & AHC_ULTRA2) != 0)
5064 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
5065 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
5066 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
5067
5068
5069 ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) & ~SELBUSB);
5070 }
5071 term = (ahc->flags & AHC_TERM_ENB_A) != 0 ? STPWEN : 0;
5072 if ((ahc->features & AHC_ULTRA2) != 0)
5073 ahc_outb(ahc, SCSIID_ULTRA2, ahc->our_id);
5074 else
5075 ahc_outb(ahc, SCSIID, ahc->our_id);
5076 scsi_conf = ahc_inb(ahc, SCSICONF);
5077 ahc_outb(ahc, SXFRCTL1, (scsi_conf & (ENSPCHK|STIMESEL))
5078 |term|ahc->seltime
5079 |ENSTIMER|ACTNEGEN);
5080 if ((ahc->features & AHC_ULTRA2) != 0)
5081 ahc_outb(ahc, SIMODE0, ahc_inb(ahc, SIMODE0)|ENIOERR);
5082 ahc_outb(ahc, SIMODE1, ENSELTIMO|ENSCSIRST|ENSCSIPERR);
5083 ahc_outb(ahc, SXFRCTL0, DFON|SPIOEN);
5084
5085
5086 for (i = 0; i < 16; i++) {
5087 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0));
5088 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5089 int lun;
5090
5091
5092
5093
5094
5095 for (lun = 1; lun < AHC_NUM_LUNS; lun++)
5096 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, lun));
5097 }
5098 }
5099
5100
5101 for (i = 0; i < 256; i++)
5102 ahc->qoutfifo[i] = SCB_LIST_NULL;
5103 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_PREREAD);
5104
5105 for (i = 0; i < 256; i++)
5106 ahc->qinfifo[i] = SCB_LIST_NULL;
5107
5108 if ((ahc->features & AHC_MULTI_TID) != 0) {
5109 ahc_outb(ahc, TARGID, 0);
5110 ahc_outb(ahc, TARGID + 1, 0);
5111 }
5112
5113
5114
5115
5116 physaddr = ahc->scb_data->hscb_busaddr;
5117 ahc_outb(ahc, HSCB_ADDR, physaddr & 0xFF);
5118 ahc_outb(ahc, HSCB_ADDR + 1, (physaddr >> 8) & 0xFF);
5119 ahc_outb(ahc, HSCB_ADDR + 2, (physaddr >> 16) & 0xFF);
5120 ahc_outb(ahc, HSCB_ADDR + 3, (physaddr >> 24) & 0xFF);
5121
5122 physaddr = ahc->shared_data_busaddr;
5123 ahc_outb(ahc, SHARED_DATA_ADDR, physaddr & 0xFF);
5124 ahc_outb(ahc, SHARED_DATA_ADDR + 1, (physaddr >> 8) & 0xFF);
5125 ahc_outb(ahc, SHARED_DATA_ADDR + 2, (physaddr >> 16) & 0xFF);
5126 ahc_outb(ahc, SHARED_DATA_ADDR + 3, (physaddr >> 24) & 0xFF);
5127
5128
5129
5130
5131
5132
5133 ahc_outb(ahc, CMDSIZE_TABLE, 5);
5134 ahc_outb(ahc, CMDSIZE_TABLE + 1, 9);
5135 ahc_outb(ahc, CMDSIZE_TABLE + 2, 9);
5136 ahc_outb(ahc, CMDSIZE_TABLE + 3, 0);
5137 ahc_outb(ahc, CMDSIZE_TABLE + 4, 15);
5138 ahc_outb(ahc, CMDSIZE_TABLE + 5, 11);
5139 ahc_outb(ahc, CMDSIZE_TABLE + 6, 0);
5140 ahc_outb(ahc, CMDSIZE_TABLE + 7, 0);
5141
5142 if ((ahc->features & AHC_HS_MAILBOX) != 0)
5143 ahc_outb(ahc, HS_MAILBOX, 0);
5144
5145
5146 if ((ahc->features & AHC_TARGETMODE) != 0) {
5147 ahc->tqinfifonext = 1;
5148 ahc_outb(ahc, KERNEL_TQINPOS, ahc->tqinfifonext - 1);
5149 ahc_outb(ahc, TQINPOS, ahc->tqinfifonext);
5150 }
5151 ahc->qinfifonext = 0;
5152 ahc->qoutfifonext = 0;
5153 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5154 ahc_outb(ahc, QOFF_CTLSTA, SCB_QSIZE_256);
5155 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5156 ahc_outb(ahc, SNSCB_QOFF, ahc->qinfifonext);
5157 ahc_outb(ahc, SDSCB_QOFF, 0);
5158 } else {
5159 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5160 ahc_outb(ahc, QINPOS, ahc->qinfifonext);
5161 ahc_outb(ahc, QOUTPOS, ahc->qoutfifonext);
5162 }
5163
5164
5165 ahc_outb(ahc, WAITING_SCBH, SCB_LIST_NULL);
5166
5167
5168 ahc_outb(ahc, DISCONNECTED_SCBH, SCB_LIST_NULL);
5169
5170
5171 ahc_outb(ahc, MSG_OUT, NOP);
5172
5173
5174
5175
5176
5177
5178 scsiseq_template = ENSELO|ENAUTOATNO|ENAUTOATNP;
5179 if ((ahc->flags & AHC_INITIATORROLE) != 0)
5180 scsiseq_template |= ENRSELI;
5181 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq_template);
5182
5183
5184 ahc_build_free_scb_list(ahc);
5185
5186
5187
5188
5189 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
5190
5191
5192
5193
5194
5195 if (bootverbose)
5196 printk("%s: Downloading Sequencer Program...",
5197 ahc_name(ahc));
5198
5199 error = ahc_loadseq(ahc);
5200 if (error != 0)
5201 return (error);
5202
5203 if ((ahc->features & AHC_ULTRA2) != 0) {
5204 int wait;
5205
5206
5207
5208
5209
5210
5211
5212
5213 for (wait = 5000;
5214 (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
5215 wait--)
5216 ahc_delay(100);
5217 }
5218 ahc_restart(ahc);
5219 return (0);
5220 }
5221
5222
5223
5224
5225 int
5226 ahc_init(struct ahc_softc *ahc)
5227 {
5228 int max_targ;
5229 u_int i;
5230 u_int scsi_conf;
5231 u_int ultraenb;
5232 u_int discenable;
5233 u_int tagenable;
5234 size_t driver_data_size;
5235
5236 #ifdef AHC_DEBUG
5237 if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0)
5238 ahc->flags |= AHC_SEQUENCER_DEBUG;
5239 #endif
5240
5241 #ifdef AHC_PRINT_SRAM
5242 printk("Scratch Ram:");
5243 for (i = 0x20; i < 0x5f; i++) {
5244 if (((i % 8) == 0) && (i != 0)) {
5245 printk ("\n ");
5246 }
5247 printk (" 0x%x", ahc_inb(ahc, i));
5248 }
5249 if ((ahc->features & AHC_MORE_SRAM) != 0) {
5250 for (i = 0x70; i < 0x7f; i++) {
5251 if (((i % 8) == 0) && (i != 0)) {
5252 printk ("\n ");
5253 }
5254 printk (" 0x%x", ahc_inb(ahc, i));
5255 }
5256 }
5257 printk ("\n");
5258
5259
5260
5261
5262 ahc_outb(ahc, CLRINT, CLRPARERR);
5263 ahc_outb(ahc, CLRINT, CLRBRKADRINT);
5264 #endif
5265 max_targ = 15;
5266
5267
5268
5269
5270 if ((ahc->flags & AHC_USEDEFAULTS) != 0)
5271 ahc->our_id = ahc->our_id_b = 7;
5272
5273
5274
5275
5276 ahc->flags |= AHC_INITIATORROLE;
5277
5278
5279
5280
5281 if ((AHC_TMODE_ENABLE & (0x1 << ahc->unit)) == 0)
5282 ahc->features &= ~AHC_TARGETMODE;
5283
5284 ahc->init_level++;
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295 driver_data_size = 2 * 256 * sizeof(uint8_t);
5296 if ((ahc->features & AHC_TARGETMODE) != 0)
5297 driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
5298 + 1;
5299 if (ahc_dma_tag_create(ahc, ahc->parent_dmat, 1,
5300 BUS_SPACE_MAXADDR_32BIT + 1,
5301 BUS_SPACE_MAXADDR_32BIT,
5302 BUS_SPACE_MAXADDR,
5303 NULL, NULL,
5304 driver_data_size,
5305 1,
5306 BUS_SPACE_MAXSIZE_32BIT,
5307 0, &ahc->shared_data_dmat) != 0) {
5308 return (ENOMEM);
5309 }
5310
5311 ahc->init_level++;
5312
5313
5314 if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
5315 (void **)&ahc->qoutfifo,
5316 BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
5317 return (ENOMEM);
5318 }
5319
5320 ahc->init_level++;
5321
5322
5323 ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
5324 ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
5325 &ahc->shared_data_busaddr, 0);
5326
5327 if ((ahc->features & AHC_TARGETMODE) != 0) {
5328 ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo;
5329 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS];
5330 ahc->dma_bug_buf = ahc->shared_data_busaddr
5331 + driver_data_size - 1;
5332
5333 for (i = 0; i < AHC_TMODE_CMDS; i++)
5334 ahc->targetcmds[i].cmd_valid = 0;
5335 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_PREREAD);
5336 ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256];
5337 }
5338 ahc->qinfifo = &ahc->qoutfifo[256];
5339
5340 ahc->init_level++;
5341
5342
5343 if (ahc->scb_data->maxhscbs == 0)
5344 if (ahc_init_scbdata(ahc) != 0)
5345 return (ENOMEM);
5346
5347
5348
5349
5350
5351
5352 if (ahc_alloc_tstate(ahc, ahc->our_id, 'A') == NULL) {
5353 printk("%s: unable to allocate ahc_tmode_tstate. "
5354 "Failing attach\n", ahc_name(ahc));
5355 return (ENOMEM);
5356 }
5357
5358 if ((ahc->features & AHC_TWIN) != 0) {
5359 if (ahc_alloc_tstate(ahc, ahc->our_id_b, 'B') == NULL) {
5360 printk("%s: unable to allocate ahc_tmode_tstate. "
5361 "Failing attach\n", ahc_name(ahc));
5362 return (ENOMEM);
5363 }
5364 }
5365
5366 if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
5367 ahc->flags |= AHC_PAGESCBS;
5368 } else {
5369 ahc->flags &= ~AHC_PAGESCBS;
5370 }
5371
5372 #ifdef AHC_DEBUG
5373 if (ahc_debug & AHC_SHOW_MISC) {
5374 printk("%s: hardware scb %u bytes; kernel scb %u bytes; "
5375 "ahc_dma %u bytes\n",
5376 ahc_name(ahc),
5377 (u_int)sizeof(struct hardware_scb),
5378 (u_int)sizeof(struct scb),
5379 (u_int)sizeof(struct ahc_dma_seg));
5380 }
5381 #endif
5382
5383
5384
5385
5386
5387 if (ahc->features & AHC_TWIN) {
5388 scsi_conf = ahc_inb(ahc, SCSICONF + 1);
5389 if ((scsi_conf & RESET_SCSI) != 0
5390 && (ahc->flags & AHC_INITIATORROLE) != 0)
5391 ahc->flags |= AHC_RESET_BUS_B;
5392 }
5393
5394 scsi_conf = ahc_inb(ahc, SCSICONF);
5395 if ((scsi_conf & RESET_SCSI) != 0
5396 && (ahc->flags & AHC_INITIATORROLE) != 0)
5397 ahc->flags |= AHC_RESET_BUS_A;
5398
5399 ultraenb = 0;
5400 tagenable = ALL_TARGETS_MASK;
5401
5402
5403 if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
5404 printk("%s: Host Adapter Bios disabled. Using default SCSI "
5405 "device parameters\n", ahc_name(ahc));
5406 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
5407 AHC_TERM_ENB_A|AHC_TERM_ENB_B;
5408 discenable = ALL_TARGETS_MASK;
5409 if ((ahc->features & AHC_ULTRA) != 0)
5410 ultraenb = ALL_TARGETS_MASK;
5411 } else {
5412 discenable = ~((ahc_inb(ahc, DISC_DSB + 1) << 8)
5413 | ahc_inb(ahc, DISC_DSB));
5414 if ((ahc->features & (AHC_ULTRA|AHC_ULTRA2)) != 0)
5415 ultraenb = (ahc_inb(ahc, ULTRA_ENB + 1) << 8)
5416 | ahc_inb(ahc, ULTRA_ENB);
5417 }
5418
5419 if ((ahc->features & (AHC_WIDE|AHC_TWIN)) == 0)
5420 max_targ = 7;
5421
5422 for (i = 0; i <= max_targ; i++) {
5423 struct ahc_initiator_tinfo *tinfo;
5424 struct ahc_tmode_tstate *tstate;
5425 u_int our_id;
5426 u_int target_id;
5427 char channel;
5428
5429 channel = 'A';
5430 our_id = ahc->our_id;
5431 target_id = i;
5432 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
5433 channel = 'B';
5434 our_id = ahc->our_id_b;
5435 target_id = i % 8;
5436 }
5437 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
5438 target_id, &tstate);
5439
5440 memset(tinfo, 0, sizeof(*tinfo));
5441 if (ahc->flags & AHC_USEDEFAULTS) {
5442 if ((ahc->features & AHC_WIDE) != 0)
5443 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
5444
5445
5446
5447
5448
5449 tinfo->user.period = ahc_syncrates->period;
5450 tinfo->user.offset = MAX_OFFSET;
5451 } else {
5452 u_int scsirate;
5453 uint16_t mask;
5454
5455
5456 scsirate = ahc_inb(ahc, TARG_SCSIRATE + i);
5457 mask = (0x01 << i);
5458 if ((ahc->features & AHC_ULTRA2) != 0) {
5459 u_int offset;
5460 u_int maxsync;
5461
5462 if ((scsirate & SOFS) == 0x0F) {
5463
5464
5465
5466
5467 scsirate = (scsirate & SXFR) >> 4
5468 | (ultraenb & mask)
5469 ? 0x08 : 0x0
5470 | (scsirate & WIDEXFER);
5471 offset = MAX_OFFSET_ULTRA2;
5472 } else
5473 offset = ahc_inb(ahc, TARG_OFFSET + i);
5474 if ((scsirate & ~WIDEXFER) == 0 && offset != 0)
5475
5476 scsirate |= 0x1c;
5477 maxsync = AHC_SYNCRATE_ULTRA2;
5478 if ((ahc->features & AHC_DT) != 0)
5479 maxsync = AHC_SYNCRATE_DT;
5480 tinfo->user.period =
5481 ahc_find_period(ahc, scsirate, maxsync);
5482 if (offset == 0)
5483 tinfo->user.period = 0;
5484 else
5485 tinfo->user.offset = MAX_OFFSET;
5486 if ((scsirate & SXFR_ULTRA2) <= 8
5487 && (ahc->features & AHC_DT) != 0)
5488 tinfo->user.ppr_options =
5489 MSG_EXT_PPR_DT_REQ;
5490 } else if ((scsirate & SOFS) != 0) {
5491 if ((scsirate & SXFR) == 0x40
5492 && (ultraenb & mask) != 0) {
5493
5494 scsirate &= ~SXFR;
5495 ultraenb &= ~mask;
5496 }
5497 tinfo->user.period =
5498 ahc_find_period(ahc, scsirate,
5499 (ultraenb & mask)
5500 ? AHC_SYNCRATE_ULTRA
5501 : AHC_SYNCRATE_FAST);
5502 if (tinfo->user.period != 0)
5503 tinfo->user.offset = MAX_OFFSET;
5504 }
5505 if (tinfo->user.period == 0)
5506 tinfo->user.offset = 0;
5507 if ((scsirate & WIDEXFER) != 0
5508 && (ahc->features & AHC_WIDE) != 0)
5509 tinfo->user.width = MSG_EXT_WDTR_BUS_16_BIT;
5510 tinfo->user.protocol_version = 4;
5511 if ((ahc->features & AHC_DT) != 0)
5512 tinfo->user.transport_version = 3;
5513 else
5514 tinfo->user.transport_version = 2;
5515 tinfo->goal.protocol_version = 2;
5516 tinfo->goal.transport_version = 2;
5517 tinfo->curr.protocol_version = 2;
5518 tinfo->curr.transport_version = 2;
5519 }
5520 tstate->ultraenb = 0;
5521 }
5522 ahc->user_discenable = discenable;
5523 ahc->user_tagenable = tagenable;
5524
5525 return (ahc->bus_chip_init(ahc));
5526 }
5527
5528 void
5529 ahc_intr_enable(struct ahc_softc *ahc, int enable)
5530 {
5531 u_int hcntrl;
5532
5533 hcntrl = ahc_inb(ahc, HCNTRL);
5534 hcntrl &= ~INTEN;
5535 ahc->pause &= ~INTEN;
5536 ahc->unpause &= ~INTEN;
5537 if (enable) {
5538 hcntrl |= INTEN;
5539 ahc->pause |= INTEN;
5540 ahc->unpause |= INTEN;
5541 }
5542 ahc_outb(ahc, HCNTRL, hcntrl);
5543 }
5544
5545
5546
5547
5548
5549
5550
5551
5552 void
5553 ahc_pause_and_flushwork(struct ahc_softc *ahc)
5554 {
5555 int intstat;
5556 int maxloops;
5557 int paused;
5558
5559 maxloops = 1000;
5560 ahc->flags |= AHC_ALL_INTERRUPTS;
5561 paused = FALSE;
5562 do {
5563 if (paused) {
5564 ahc_unpause(ahc);
5565
5566
5567
5568
5569 ahc_delay(500);
5570 }
5571 ahc_intr(ahc);
5572 ahc_pause(ahc);
5573 paused = TRUE;
5574 ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);
5575 intstat = ahc_inb(ahc, INTSTAT);
5576 if ((intstat & INT_PEND) == 0) {
5577 ahc_clear_critical_section(ahc);
5578 intstat = ahc_inb(ahc, INTSTAT);
5579 }
5580 } while (--maxloops
5581 && (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0)
5582 && ((intstat & INT_PEND) != 0
5583 || (ahc_inb(ahc, SSTAT0) & (SELDO|SELINGO)) != 0));
5584 if (maxloops == 0) {
5585 printk("Infinite interrupt loop, INTSTAT = %x",
5586 ahc_inb(ahc, INTSTAT));
5587 }
5588 ahc_platform_flushwork(ahc);
5589 ahc->flags &= ~AHC_ALL_INTERRUPTS;
5590 }
5591
5592 int __maybe_unused
5593 ahc_suspend(struct ahc_softc *ahc)
5594 {
5595
5596 ahc_pause_and_flushwork(ahc);
5597
5598 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
5599 ahc_unpause(ahc);
5600 return (EBUSY);
5601 }
5602
5603 #ifdef AHC_TARGET_MODE
5604
5605
5606
5607
5608
5609 if (ahc->pending_device != NULL) {
5610 ahc_unpause(ahc);
5611 return (EBUSY);
5612 }
5613 #endif
5614 ahc_shutdown(ahc);
5615 return (0);
5616 }
5617
5618 int __maybe_unused
5619 ahc_resume(struct ahc_softc *ahc)
5620 {
5621
5622 ahc_reset(ahc, TRUE);
5623 ahc_intr_enable(ahc, TRUE);
5624 ahc_restart(ahc);
5625 return (0);
5626 }
5627
5628
5629
5630
5631
5632 static u_int
5633 ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl)
5634 {
5635 u_int scbid;
5636 u_int target_offset;
5637
5638 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5639 u_int saved_scbptr;
5640
5641 saved_scbptr = ahc_inb(ahc, SCBPTR);
5642 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5643 scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
5644 ahc_outb(ahc, SCBPTR, saved_scbptr);
5645 } else {
5646 target_offset = TCL_TARGET_OFFSET(tcl);
5647 scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
5648 }
5649
5650 return (scbid);
5651 }
5652
5653 static void
5654 ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl)
5655 {
5656 u_int target_offset;
5657
5658 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5659 u_int saved_scbptr;
5660
5661 saved_scbptr = ahc_inb(ahc, SCBPTR);
5662 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5663 ahc_outb(ahc, SCB_64_BTT+TCL_TARGET_OFFSET(tcl), SCB_LIST_NULL);
5664 ahc_outb(ahc, SCBPTR, saved_scbptr);
5665 } else {
5666 target_offset = TCL_TARGET_OFFSET(tcl);
5667 ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
5668 }
5669 }
5670
5671 static void
5672 ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid)
5673 {
5674 u_int target_offset;
5675
5676 if ((ahc->flags & AHC_SCB_BTT) != 0) {
5677 u_int saved_scbptr;
5678
5679 saved_scbptr = ahc_inb(ahc, SCBPTR);
5680 ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
5681 ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl), scbid);
5682 ahc_outb(ahc, SCBPTR, saved_scbptr);
5683 } else {
5684 target_offset = TCL_TARGET_OFFSET(tcl);
5685 ahc_outb(ahc, BUSY_TARGETS + target_offset, scbid);
5686 }
5687 }
5688
5689
5690 int
5691 ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target,
5692 char channel, int lun, u_int tag, role_t role)
5693 {
5694 int targ = SCB_GET_TARGET(ahc, scb);
5695 char chan = SCB_GET_CHANNEL(ahc, scb);
5696 int slun = SCB_GET_LUN(scb);
5697 int match;
5698
5699 match = ((chan == channel) || (channel == ALL_CHANNELS));
5700 if (match != 0)
5701 match = ((targ == target) || (target == CAM_TARGET_WILDCARD));
5702 if (match != 0)
5703 match = ((lun == slun) || (lun == CAM_LUN_WILDCARD));
5704 if (match != 0) {
5705 #ifdef AHC_TARGET_MODE
5706 int group;
5707
5708 group = XPT_FC_GROUP(scb->io_ctx->ccb_h.func_code);
5709 if (role == ROLE_INITIATOR) {
5710 match = (group != XPT_FC_GROUP_TMODE)
5711 && ((tag == scb->hscb->tag)
5712 || (tag == SCB_LIST_NULL));
5713 } else if (role == ROLE_TARGET) {
5714 match = (group == XPT_FC_GROUP_TMODE)
5715 && ((tag == scb->io_ctx->csio.tag_id)
5716 || (tag == SCB_LIST_NULL));
5717 }
5718 #else
5719 match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
5720 #endif
5721 }
5722
5723 return match;
5724 }
5725
5726 static void
5727 ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
5728 {
5729 int target;
5730 char channel;
5731 int lun;
5732
5733 target = SCB_GET_TARGET(ahc, scb);
5734 lun = SCB_GET_LUN(scb);
5735 channel = SCB_GET_CHANNEL(ahc, scb);
5736
5737 ahc_search_qinfifo(ahc, target, channel, lun,
5738 SCB_LIST_NULL, ROLE_UNKNOWN,
5739 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
5740
5741 ahc_platform_freeze_devq(ahc, scb);
5742 }
5743
5744 void
5745 ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb)
5746 {
5747 struct scb *prev_scb;
5748
5749 prev_scb = NULL;
5750 if (ahc_qinfifo_count(ahc) != 0) {
5751 u_int prev_tag;
5752 uint8_t prev_pos;
5753
5754 prev_pos = ahc->qinfifonext - 1;
5755 prev_tag = ahc->qinfifo[prev_pos];
5756 prev_scb = ahc_lookup_scb(ahc, prev_tag);
5757 }
5758 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5759 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5760 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5761 } else {
5762 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5763 }
5764 }
5765
5766 static void
5767 ahc_qinfifo_requeue(struct ahc_softc *ahc, struct scb *prev_scb,
5768 struct scb *scb)
5769 {
5770 if (prev_scb == NULL) {
5771 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5772 } else {
5773 prev_scb->hscb->next = scb->hscb->tag;
5774 ahc_sync_scb(ahc, prev_scb,
5775 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5776 }
5777 ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
5778 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5779 ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
5780 }
5781
5782 static int
5783 ahc_qinfifo_count(struct ahc_softc *ahc)
5784 {
5785 uint8_t qinpos;
5786 uint8_t diff;
5787
5788 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5789 qinpos = ahc_inb(ahc, SNSCB_QOFF);
5790 ahc_outb(ahc, SNSCB_QOFF, qinpos);
5791 } else
5792 qinpos = ahc_inb(ahc, QINPOS);
5793 diff = ahc->qinfifonext - qinpos;
5794 return (diff);
5795 }
5796
5797 int
5798 ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel,
5799 int lun, u_int tag, role_t role, uint32_t status,
5800 ahc_search_action action)
5801 {
5802 struct scb *scb;
5803 struct scb *prev_scb;
5804 uint8_t qinstart;
5805 uint8_t qinpos;
5806 uint8_t qintail;
5807 uint8_t next;
5808 uint8_t prev;
5809 uint8_t curscbptr;
5810 int found;
5811 int have_qregs;
5812
5813 qintail = ahc->qinfifonext;
5814 have_qregs = (ahc->features & AHC_QUEUE_REGS) != 0;
5815 if (have_qregs) {
5816 qinstart = ahc_inb(ahc, SNSCB_QOFF);
5817 ahc_outb(ahc, SNSCB_QOFF, qinstart);
5818 } else
5819 qinstart = ahc_inb(ahc, QINPOS);
5820 qinpos = qinstart;
5821 found = 0;
5822 prev_scb = NULL;
5823
5824 if (action == SEARCH_COMPLETE) {
5825
5826
5827
5828
5829 ahc_freeze_untagged_queues(ahc);
5830 }
5831
5832
5833
5834
5835
5836 ahc->qinfifonext = qinpos;
5837 ahc_outb(ahc, NEXT_QUEUED_SCB, ahc->next_queued_scb->hscb->tag);
5838
5839 while (qinpos != qintail) {
5840 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]);
5841 if (scb == NULL) {
5842 printk("qinpos = %d, SCB index = %d\n",
5843 qinpos, ahc->qinfifo[qinpos]);
5844 panic("Loop 1\n");
5845 }
5846
5847 if (ahc_match_scb(ahc, scb, target, channel, lun, tag, role)) {
5848
5849
5850
5851 found++;
5852 switch (action) {
5853 case SEARCH_COMPLETE:
5854 {
5855 cam_status ostat;
5856 cam_status cstat;
5857
5858 ostat = ahc_get_transaction_status(scb);
5859 if (ostat == CAM_REQ_INPROG)
5860 ahc_set_transaction_status(scb, status);
5861 cstat = ahc_get_transaction_status(scb);
5862 if (cstat != CAM_REQ_CMP)
5863 ahc_freeze_scb(scb);
5864 if ((scb->flags & SCB_ACTIVE) == 0)
5865 printk("Inactive SCB in qinfifo\n");
5866 ahc_done(ahc, scb);
5867 }
5868 fallthrough;
5869 case SEARCH_REMOVE:
5870 break;
5871 case SEARCH_COUNT:
5872 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5873 prev_scb = scb;
5874 break;
5875 }
5876 } else {
5877 ahc_qinfifo_requeue(ahc, prev_scb, scb);
5878 prev_scb = scb;
5879 }
5880 qinpos++;
5881 }
5882
5883 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
5884 ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
5885 } else {
5886 ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
5887 }
5888
5889 if (action != SEARCH_COUNT
5890 && (found != 0)
5891 && (qinstart != ahc->qinfifonext)) {
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]);
5905
5906 if (scb == NULL) {
5907 printk("found = %d, qinstart = %d, qinfifionext = %d\n",
5908 found, qinstart, ahc->qinfifonext);
5909 panic("First/Second Qinfifo fixup\n");
5910 }
5911
5912
5913
5914
5915
5916
5917 next = scb->hscb->next;
5918 ahc->scb_data->scbindex[scb->hscb->tag] = NULL;
5919 ahc_swap_with_next_hscb(ahc, scb);
5920 scb->hscb->next = next;
5921 ahc->qinfifo[qinstart] = scb->hscb->tag;
5922
5923
5924 ahc_outb(ahc, NEXT_QUEUED_SCB, scb->hscb->tag);
5925
5926
5927 qintail = ahc->qinfifonext - 1;
5928 scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]);
5929 scb->hscb->next = ahc->next_queued_scb->hscb->tag;
5930 }
5931
5932
5933
5934
5935 curscbptr = ahc_inb(ahc, SCBPTR);
5936 next = ahc_inb(ahc, WAITING_SCBH);
5937 prev = SCB_LIST_NULL;
5938
5939 while (next != SCB_LIST_NULL) {
5940 uint8_t scb_index;
5941
5942 ahc_outb(ahc, SCBPTR, next);
5943 scb_index = ahc_inb(ahc, SCB_TAG);
5944 if (scb_index >= ahc->scb_data->numscbs) {
5945 printk("Waiting List inconsistency. "
5946 "SCB index == %d, yet numscbs == %d.",
5947 scb_index, ahc->scb_data->numscbs);
5948 ahc_dump_card_state(ahc);
5949 panic("for safety");
5950 }
5951 scb = ahc_lookup_scb(ahc, scb_index);
5952 if (scb == NULL) {
5953 printk("scb_index = %d, next = %d\n",
5954 scb_index, next);
5955 panic("Waiting List traversal\n");
5956 }
5957 if (ahc_match_scb(ahc, scb, target, channel,
5958 lun, SCB_LIST_NULL, role)) {
5959
5960
5961
5962 found++;
5963 switch (action) {
5964 case SEARCH_COMPLETE:
5965 {
5966 cam_status ostat;
5967 cam_status cstat;
5968
5969 ostat = ahc_get_transaction_status(scb);
5970 if (ostat == CAM_REQ_INPROG)
5971 ahc_set_transaction_status(scb,
5972 status);
5973 cstat = ahc_get_transaction_status(scb);
5974 if (cstat != CAM_REQ_CMP)
5975 ahc_freeze_scb(scb);
5976 if ((scb->flags & SCB_ACTIVE) == 0)
5977 printk("Inactive SCB in Waiting List\n");
5978 ahc_done(ahc, scb);
5979 }
5980 fallthrough;
5981 case SEARCH_REMOVE:
5982 next = ahc_rem_wscb(ahc, next, prev);
5983 break;
5984 case SEARCH_COUNT:
5985 prev = next;
5986 next = ahc_inb(ahc, SCB_NEXT);
5987 break;
5988 }
5989 } else {
5990 prev = next;
5991 next = ahc_inb(ahc, SCB_NEXT);
5992 }
5993 }
5994 ahc_outb(ahc, SCBPTR, curscbptr);
5995
5996 found += ahc_search_untagged_queues(ahc, NULL, target,
5997 channel, lun, status, action);
5998
5999 if (action == SEARCH_COMPLETE)
6000 ahc_release_untagged_queues(ahc);
6001 return (found);
6002 }
6003
6004 int
6005 ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
6006 int target, char channel, int lun, uint32_t status,
6007 ahc_search_action action)
6008 {
6009 struct scb *scb;
6010 int maxtarget;
6011 int found;
6012 int i;
6013
6014 if (action == SEARCH_COMPLETE) {
6015
6016
6017
6018
6019 ahc_freeze_untagged_queues(ahc);
6020 }
6021
6022 found = 0;
6023 i = 0;
6024 if ((ahc->flags & AHC_SCB_BTT) == 0) {
6025
6026 maxtarget = 16;
6027 if (target != CAM_TARGET_WILDCARD) {
6028
6029 i = target;
6030 if (channel == 'B')
6031 i += 8;
6032 maxtarget = i + 1;
6033 }
6034 } else {
6035 maxtarget = 0;
6036 }
6037
6038 for (; i < maxtarget; i++) {
6039 struct scb_tailq *untagged_q;
6040 struct scb *next_scb;
6041
6042 untagged_q = &(ahc->untagged_queues[i]);
6043 next_scb = TAILQ_FIRST(untagged_q);
6044 while (next_scb != NULL) {
6045
6046 scb = next_scb;
6047 next_scb = TAILQ_NEXT(scb, links.tqe);
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058 if ((scb->flags & SCB_ACTIVE) != 0)
6059 continue;
6060
6061 if (ahc_match_scb(ahc, scb, target, channel, lun,
6062 SCB_LIST_NULL, ROLE_INITIATOR) == 0
6063 || (ctx != NULL && ctx != scb->io_ctx))
6064 continue;
6065
6066
6067
6068
6069 found++;
6070 switch (action) {
6071 case SEARCH_COMPLETE:
6072 {
6073 cam_status ostat;
6074 cam_status cstat;
6075
6076 ostat = ahc_get_transaction_status(scb);
6077 if (ostat == CAM_REQ_INPROG)
6078 ahc_set_transaction_status(scb, status);
6079 cstat = ahc_get_transaction_status(scb);
6080 if (cstat != CAM_REQ_CMP)
6081 ahc_freeze_scb(scb);
6082 if ((scb->flags & SCB_ACTIVE) == 0)
6083 printk("Inactive SCB in untaggedQ\n");
6084 ahc_done(ahc, scb);
6085 break;
6086 }
6087 case SEARCH_REMOVE:
6088 scb->flags &= ~SCB_UNTAGGEDQ;
6089 TAILQ_REMOVE(untagged_q, scb, links.tqe);
6090 break;
6091 case SEARCH_COUNT:
6092 break;
6093 }
6094 }
6095 }
6096
6097 if (action == SEARCH_COMPLETE)
6098 ahc_release_untagged_queues(ahc);
6099 return (found);
6100 }
6101
6102 int
6103 ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel,
6104 int lun, u_int tag, int stop_on_first, int remove,
6105 int save_state)
6106 {
6107 struct scb *scbp;
6108 u_int next;
6109 u_int prev;
6110 u_int count;
6111 u_int active_scb;
6112
6113 count = 0;
6114 next = ahc_inb(ahc, DISCONNECTED_SCBH);
6115 prev = SCB_LIST_NULL;
6116
6117 if (save_state) {
6118
6119 active_scb = ahc_inb(ahc, SCBPTR);
6120 } else
6121
6122 active_scb = SCB_LIST_NULL;
6123
6124 while (next != SCB_LIST_NULL) {
6125 u_int scb_index;
6126
6127 ahc_outb(ahc, SCBPTR, next);
6128 scb_index = ahc_inb(ahc, SCB_TAG);
6129 if (scb_index >= ahc->scb_data->numscbs) {
6130 printk("Disconnected List inconsistency. "
6131 "SCB index == %d, yet numscbs == %d.",
6132 scb_index, ahc->scb_data->numscbs);
6133 ahc_dump_card_state(ahc);
6134 panic("for safety");
6135 }
6136
6137 if (next == prev) {
6138 panic("Disconnected List Loop. "
6139 "cur SCBPTR == %x, prev SCBPTR == %x.",
6140 next, prev);
6141 }
6142 scbp = ahc_lookup_scb(ahc, scb_index);
6143 if (ahc_match_scb(ahc, scbp, target, channel, lun,
6144 tag, ROLE_INITIATOR)) {
6145 count++;
6146 if (remove) {
6147 next =
6148 ahc_rem_scb_from_disc_list(ahc, prev, next);
6149 } else {
6150 prev = next;
6151 next = ahc_inb(ahc, SCB_NEXT);
6152 }
6153 if (stop_on_first)
6154 break;
6155 } else {
6156 prev = next;
6157 next = ahc_inb(ahc, SCB_NEXT);
6158 }
6159 }
6160 if (save_state)
6161 ahc_outb(ahc, SCBPTR, active_scb);
6162 return (count);
6163 }
6164
6165
6166
6167
6168
6169 static u_int
6170 ahc_rem_scb_from_disc_list(struct ahc_softc *ahc, u_int prev, u_int scbptr)
6171 {
6172 u_int next;
6173
6174 ahc_outb(ahc, SCBPTR, scbptr);
6175 next = ahc_inb(ahc, SCB_NEXT);
6176
6177 ahc_outb(ahc, SCB_CONTROL, 0);
6178
6179 ahc_add_curscb_to_free_list(ahc);
6180
6181 if (prev != SCB_LIST_NULL) {
6182 ahc_outb(ahc, SCBPTR, prev);
6183 ahc_outb(ahc, SCB_NEXT, next);
6184 } else
6185 ahc_outb(ahc, DISCONNECTED_SCBH, next);
6186
6187 return (next);
6188 }
6189
6190
6191
6192
6193
6194
6195 static void
6196 ahc_add_curscb_to_free_list(struct ahc_softc *ahc)
6197 {
6198
6199
6200
6201
6202 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
6203
6204 if ((ahc->flags & AHC_PAGESCBS) != 0) {
6205 ahc_outb(ahc, SCB_NEXT, ahc_inb(ahc, FREE_SCBH));
6206 ahc_outb(ahc, FREE_SCBH, ahc_inb(ahc, SCBPTR));
6207 }
6208 }
6209
6210
6211
6212
6213
6214 static u_int
6215 ahc_rem_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev)
6216 {
6217 u_int curscb, next;
6218
6219
6220
6221
6222
6223 curscb = ahc_inb(ahc, SCBPTR);
6224 ahc_outb(ahc, SCBPTR, scbpos);
6225 next = ahc_inb(ahc, SCB_NEXT);
6226
6227
6228 ahc_outb(ahc, SCB_CONTROL, 0);
6229
6230 ahc_add_curscb_to_free_list(ahc);
6231
6232
6233 if (prev == SCB_LIST_NULL) {
6234
6235 ahc_outb(ahc, WAITING_SCBH, next);
6236
6237
6238
6239
6240
6241 ahc_outb(ahc, SCSISEQ, (ahc_inb(ahc, SCSISEQ) & ~ENSELO));
6242 } else {
6243
6244
6245
6246
6247 ahc_outb(ahc, SCBPTR, prev);
6248 ahc_outb(ahc, SCB_NEXT, next);
6249 }
6250
6251
6252
6253
6254 ahc_outb(ahc, SCBPTR, curscb);
6255 return next;
6256 }
6257
6258
6259
6260
6261
6262
6263
6264
6265 static int
6266 ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
6267 int lun, u_int tag, role_t role, uint32_t status)
6268 {
6269 struct scb *scbp;
6270 struct scb *scbp_next;
6271 u_int active_scb;
6272 int i, j;
6273 int maxtarget;
6274 int minlun;
6275 int maxlun;
6276
6277 int found;
6278
6279
6280
6281
6282
6283 ahc_freeze_untagged_queues(ahc);
6284
6285
6286 active_scb = ahc_inb(ahc, SCBPTR);
6287
6288 found = ahc_search_qinfifo(ahc, target, channel, lun, SCB_LIST_NULL,
6289 role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
6290
6291
6292
6293
6294 i = 0;
6295 maxtarget = 16;
6296 if (target != CAM_TARGET_WILDCARD) {
6297 i = target;
6298 if (channel == 'B')
6299 i += 8;
6300 maxtarget = i + 1;
6301 }
6302
6303 if (lun == CAM_LUN_WILDCARD) {
6304
6305
6306
6307
6308
6309
6310
6311 minlun = 0;
6312 maxlun = 1;
6313 if ((ahc->flags & AHC_SCB_BTT) != 0)
6314 maxlun = AHC_NUM_LUNS;
6315 } else {
6316 minlun = lun;
6317 maxlun = lun + 1;
6318 }
6319
6320 if (role != ROLE_TARGET) {
6321 for (;i < maxtarget; i++) {
6322 for (j = minlun;j < maxlun; j++) {
6323 u_int scbid;
6324 u_int tcl;
6325
6326 tcl = BUILD_TCL(i << 4, j);
6327 scbid = ahc_index_busy_tcl(ahc, tcl);
6328 scbp = ahc_lookup_scb(ahc, scbid);
6329 if (scbp == NULL
6330 || ahc_match_scb(ahc, scbp, target, channel,
6331 lun, tag, role) == 0)
6332 continue;
6333 ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, j));
6334 }
6335 }
6336
6337
6338
6339
6340
6341
6342
6343 ahc_search_disc_list(ahc, target, channel, lun, tag,
6344 FALSE, TRUE,
6345 FALSE);
6346 }
6347
6348
6349
6350
6351
6352
6353
6354
6355 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
6356 u_int scbid;
6357
6358 ahc_outb(ahc, SCBPTR, i);
6359 scbid = ahc_inb(ahc, SCB_TAG);
6360 scbp = ahc_lookup_scb(ahc, scbid);
6361 if ((scbp == NULL && scbid != SCB_LIST_NULL)
6362 || (scbp != NULL
6363 && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)))
6364 ahc_add_curscb_to_free_list(ahc);
6365 }
6366
6367
6368
6369
6370
6371
6372
6373 scbp_next = LIST_FIRST(&ahc->pending_scbs);
6374 while (scbp_next != NULL) {
6375 scbp = scbp_next;
6376 scbp_next = LIST_NEXT(scbp, pending_links);
6377 if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
6378 cam_status ostat;
6379
6380 ostat = ahc_get_transaction_status(scbp);
6381 if (ostat == CAM_REQ_INPROG)
6382 ahc_set_transaction_status(scbp, status);
6383 if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
6384 ahc_freeze_scb(scbp);
6385 if ((scbp->flags & SCB_ACTIVE) == 0)
6386 printk("Inactive SCB on pending list\n");
6387 ahc_done(ahc, scbp);
6388 found++;
6389 }
6390 }
6391 ahc_outb(ahc, SCBPTR, active_scb);
6392 ahc_platform_abort_scbs(ahc, target, channel, lun, tag, role, status);
6393 ahc_release_untagged_queues(ahc);
6394 return found;
6395 }
6396
6397 static void
6398 ahc_reset_current_bus(struct ahc_softc *ahc)
6399 {
6400 uint8_t scsiseq;
6401
6402 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
6403 scsiseq = ahc_inb(ahc, SCSISEQ);
6404 ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
6405 ahc_flush_device_writes(ahc);
6406 ahc_delay(AHC_BUSRESET_DELAY);
6407
6408 ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
6409
6410 ahc_clear_intstat(ahc);
6411
6412
6413 ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) | ENSCSIRST);
6414 }
6415
6416 int
6417 ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
6418 {
6419 struct ahc_devinfo devinfo;
6420 u_int initiator, target, max_scsiid;
6421 u_int sblkctl;
6422 u_int scsiseq;
6423 u_int simode1;
6424 int found;
6425 int restart_needed;
6426 char cur_channel;
6427
6428 ahc->pending_device = NULL;
6429
6430 ahc_compile_devinfo(&devinfo,
6431 CAM_TARGET_WILDCARD,
6432 CAM_TARGET_WILDCARD,
6433 CAM_LUN_WILDCARD,
6434 channel, ROLE_UNKNOWN);
6435 ahc_pause(ahc);
6436
6437
6438 ahc_clear_critical_section(ahc);
6439
6440
6441
6442
6443
6444
6445 ahc_run_qoutfifo(ahc);
6446 #ifdef AHC_TARGET_MODE
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457 if ((ahc->flags & AHC_TARGETROLE) != 0) {
6458 ahc_run_tqinfifo(ahc, TRUE);
6459 }
6460 #endif
6461
6462
6463
6464
6465 sblkctl = ahc_inb(ahc, SBLKCTL);
6466 cur_channel = 'A';
6467 if ((ahc->features & AHC_TWIN) != 0
6468 && ((sblkctl & SELBUSB) != 0))
6469 cur_channel = 'B';
6470 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
6471 if (cur_channel != channel) {
6472
6473
6474
6475
6476 ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
6477 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
6478 #ifdef AHC_TARGET_MODE
6479
6480
6481
6482
6483
6484 if ((ahc->flags & AHC_TARGETROLE) != 0)
6485 simode1 |= ENSCSIRST;
6486 #endif
6487 ahc_outb(ahc, SIMODE1, simode1);
6488 if (initiate_reset)
6489 ahc_reset_current_bus(ahc);
6490 ahc_clear_intstat(ahc);
6491 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
6492 ahc_outb(ahc, SBLKCTL, sblkctl);
6493 restart_needed = FALSE;
6494 } else {
6495
6496 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
6497 #ifdef AHC_TARGET_MODE
6498
6499
6500
6501
6502
6503 if ((ahc->flags & AHC_TARGETROLE) != 0)
6504 simode1 |= ENSCSIRST;
6505 #endif
6506 ahc_outb(ahc, SIMODE1, simode1);
6507 if (initiate_reset)
6508 ahc_reset_current_bus(ahc);
6509 ahc_clear_intstat(ahc);
6510 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
6511 restart_needed = TRUE;
6512 }
6513
6514
6515
6516
6517
6518 found = ahc_abort_scbs(ahc, CAM_TARGET_WILDCARD, channel,
6519 CAM_LUN_WILDCARD, SCB_LIST_NULL,
6520 ROLE_UNKNOWN, CAM_SCSI_BUS_RESET);
6521
6522 max_scsiid = (ahc->features & AHC_WIDE) ? 15 : 7;
6523
6524 #ifdef AHC_TARGET_MODE
6525
6526
6527
6528
6529 for (target = 0; target <= max_scsiid; target++) {
6530 struct ahc_tmode_tstate* tstate;
6531 u_int lun;
6532
6533 tstate = ahc->enabled_targets[target];
6534 if (tstate == NULL)
6535 continue;
6536 for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
6537 struct ahc_tmode_lstate* lstate;
6538
6539 lstate = tstate->enabled_luns[lun];
6540 if (lstate == NULL)
6541 continue;
6542
6543 ahc_queue_lstate_event(ahc, lstate, CAM_TARGET_WILDCARD,
6544 EVENT_TYPE_BUS_RESET, 0);
6545 ahc_send_lstate_events(ahc, lstate);
6546 }
6547 }
6548 #endif
6549
6550 ahc_send_async(ahc, devinfo.channel, CAM_TARGET_WILDCARD,
6551 CAM_LUN_WILDCARD, AC_BUS_RESET);
6552
6553
6554
6555
6556 for (target = 0; target <= max_scsiid; target++) {
6557
6558 if (ahc->enabled_targets[target] == NULL)
6559 continue;
6560 for (initiator = 0; initiator <= max_scsiid; initiator++) {
6561 struct ahc_devinfo devinfo;
6562
6563 ahc_compile_devinfo(&devinfo, target, initiator,
6564 CAM_LUN_WILDCARD,
6565 channel, ROLE_UNKNOWN);
6566 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
6567 AHC_TRANS_CUR, TRUE);
6568 ahc_set_syncrate(ahc, &devinfo, NULL,
6569 0, 0,
6570 0, AHC_TRANS_CUR,
6571 TRUE);
6572 }
6573 }
6574
6575 if (restart_needed)
6576 ahc_restart(ahc);
6577 else
6578 ahc_unpause(ahc);
6579 return found;
6580 }
6581
6582
6583
6584
6585
6586
6587 static void
6588 ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
6589 {
6590 struct hardware_scb *hscb;
6591 struct status_pkt *spkt;
6592 uint32_t sgptr;
6593 uint32_t resid_sgptr;
6594 uint32_t resid;
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612 hscb = scb->hscb;
6613 sgptr = ahc_le32toh(hscb->sgptr);
6614 if ((sgptr & SG_RESID_VALID) == 0)
6615
6616 return;
6617 sgptr &= ~SG_RESID_VALID;
6618
6619 if ((sgptr & SG_LIST_NULL) != 0)
6620
6621 return;
6622
6623 spkt = &hscb->shared_data.status;
6624 resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
6625 if ((sgptr & SG_FULL_RESID) != 0) {
6626
6627 resid = ahc_get_transfer_length(scb);
6628 } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
6629
6630 return;
6631 } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
6632 panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
6633 } else {
6634 struct ahc_dma_seg *sg;
6635
6636
6637
6638
6639
6640 resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
6641 sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
6642
6643
6644 sg--;
6645
6646
6647
6648
6649
6650
6651 while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
6652 sg++;
6653 resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
6654 }
6655 }
6656 if ((scb->flags & SCB_SENSE) == 0)
6657 ahc_set_residual(scb, resid);
6658 else
6659 ahc_set_sense_residual(scb, resid);
6660
6661 #ifdef AHC_DEBUG
6662 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
6663 ahc_print_path(ahc, scb);
6664 printk("Handled %sResidual of %d bytes\n",
6665 (scb->flags & SCB_SENSE) ? "Sense " : "", resid);
6666 }
6667 #endif
6668 }
6669
6670
6671 #ifdef AHC_TARGET_MODE
6672
6673
6674
6675 static void
6676 ahc_queue_lstate_event(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate,
6677 u_int initiator_id, u_int event_type, u_int event_arg)
6678 {
6679 struct ahc_tmode_event *event;
6680 int pending;
6681
6682 xpt_freeze_devq(lstate->path, 1);
6683 if (lstate->event_w_idx >= lstate->event_r_idx)
6684 pending = lstate->event_w_idx - lstate->event_r_idx;
6685 else
6686 pending = AHC_TMODE_EVENT_BUFFER_SIZE + 1
6687 - (lstate->event_r_idx - lstate->event_w_idx);
6688
6689 if (event_type == EVENT_TYPE_BUS_RESET
6690 || event_type == TARGET_RESET) {
6691
6692
6693
6694
6695
6696
6697 lstate->event_r_idx = 0;
6698 lstate->event_w_idx = 0;
6699 xpt_release_devq(lstate->path, pending, FALSE);
6700 }
6701
6702 if (pending == AHC_TMODE_EVENT_BUFFER_SIZE) {
6703 xpt_print_path(lstate->path);
6704 printk("immediate event %x:%x lost\n",
6705 lstate->event_buffer[lstate->event_r_idx].event_type,
6706 lstate->event_buffer[lstate->event_r_idx].event_arg);
6707 lstate->event_r_idx++;
6708 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6709 lstate->event_r_idx = 0;
6710 xpt_release_devq(lstate->path, 1, FALSE);
6711 }
6712
6713 event = &lstate->event_buffer[lstate->event_w_idx];
6714 event->initiator_id = initiator_id;
6715 event->event_type = event_type;
6716 event->event_arg = event_arg;
6717 lstate->event_w_idx++;
6718 if (lstate->event_w_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6719 lstate->event_w_idx = 0;
6720 }
6721
6722
6723
6724
6725
6726 void
6727 ahc_send_lstate_events(struct ahc_softc *ahc, struct ahc_tmode_lstate *lstate)
6728 {
6729 struct ccb_hdr *ccbh;
6730 struct ccb_immed_notify *inot;
6731
6732 while (lstate->event_r_idx != lstate->event_w_idx
6733 && (ccbh = SLIST_FIRST(&lstate->immed_notifies)) != NULL) {
6734 struct ahc_tmode_event *event;
6735
6736 event = &lstate->event_buffer[lstate->event_r_idx];
6737 SLIST_REMOVE_HEAD(&lstate->immed_notifies, sim_links.sle);
6738 inot = (struct ccb_immed_notify *)ccbh;
6739 switch (event->event_type) {
6740 case EVENT_TYPE_BUS_RESET:
6741 ccbh->status = CAM_SCSI_BUS_RESET|CAM_DEV_QFRZN;
6742 break;
6743 default:
6744 ccbh->status = CAM_MESSAGE_RECV|CAM_DEV_QFRZN;
6745 inot->message_args[0] = event->event_type;
6746 inot->message_args[1] = event->event_arg;
6747 break;
6748 }
6749 inot->initiator_id = event->initiator_id;
6750 inot->sense_len = 0;
6751 xpt_done((union ccb *)inot);
6752 lstate->event_r_idx++;
6753 if (lstate->event_r_idx == AHC_TMODE_EVENT_BUFFER_SIZE)
6754 lstate->event_r_idx = 0;
6755 }
6756 }
6757 #endif
6758
6759
6760
6761 #ifdef AHC_DUMP_SEQ
6762 void
6763 ahc_dumpseq(struct ahc_softc* ahc)
6764 {
6765 int i;
6766
6767 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6768 ahc_outb(ahc, SEQADDR0, 0);
6769 ahc_outb(ahc, SEQADDR1, 0);
6770 for (i = 0; i < ahc->instruction_ram_size; i++) {
6771 uint8_t ins_bytes[4];
6772
6773 ahc_insb(ahc, SEQRAM, ins_bytes, 4);
6774 printk("0x%08x\n", ins_bytes[0] << 24
6775 | ins_bytes[1] << 16
6776 | ins_bytes[2] << 8
6777 | ins_bytes[3]);
6778 }
6779 }
6780 #endif
6781
6782 static int
6783 ahc_loadseq(struct ahc_softc *ahc)
6784 {
6785 struct cs cs_table[NUM_CRITICAL_SECTIONS];
6786 u_int begin_set[NUM_CRITICAL_SECTIONS];
6787 u_int end_set[NUM_CRITICAL_SECTIONS];
6788 const struct patch *cur_patch;
6789 u_int cs_count;
6790 u_int cur_cs;
6791 u_int i;
6792 u_int skip_addr;
6793 u_int sg_prefetch_cnt;
6794 int downloaded;
6795 uint8_t download_consts[7];
6796
6797
6798
6799
6800
6801 cs_count = 0;
6802 cur_cs = 0;
6803 memset(begin_set, 0, sizeof(begin_set));
6804 memset(end_set, 0, sizeof(end_set));
6805
6806
6807 download_consts[QOUTFIFO_OFFSET] = 0;
6808 if (ahc->targetcmds != NULL)
6809 download_consts[QOUTFIFO_OFFSET] += 32;
6810 download_consts[QINFIFO_OFFSET] = download_consts[QOUTFIFO_OFFSET] + 1;
6811 download_consts[CACHESIZE_MASK] = ahc->pci_cachesize - 1;
6812 download_consts[INVERTED_CACHESIZE_MASK] = ~(ahc->pci_cachesize - 1);
6813 sg_prefetch_cnt = ahc->pci_cachesize;
6814 if (sg_prefetch_cnt < (2 * sizeof(struct ahc_dma_seg)))
6815 sg_prefetch_cnt = 2 * sizeof(struct ahc_dma_seg);
6816 download_consts[SG_PREFETCH_CNT] = sg_prefetch_cnt;
6817 download_consts[SG_PREFETCH_ALIGN_MASK] = ~(sg_prefetch_cnt - 1);
6818 download_consts[SG_PREFETCH_ADDR_MASK] = (sg_prefetch_cnt - 1);
6819
6820 cur_patch = patches;
6821 downloaded = 0;
6822 skip_addr = 0;
6823 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
6824 ahc_outb(ahc, SEQADDR0, 0);
6825 ahc_outb(ahc, SEQADDR1, 0);
6826
6827 for (i = 0; i < sizeof(seqprog)/4; i++) {
6828 if (ahc_check_patch(ahc, &cur_patch, i, &skip_addr) == 0) {
6829
6830
6831
6832
6833 continue;
6834 }
6835
6836 if (downloaded == ahc->instruction_ram_size) {
6837
6838
6839
6840
6841
6842 printk("\n%s: Program too large for instruction memory "
6843 "size of %d!\n", ahc_name(ahc),
6844 ahc->instruction_ram_size);
6845 return (ENOMEM);
6846 }
6847
6848
6849
6850
6851
6852 for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) {
6853 if (critical_sections[cur_cs].end <= i) {
6854 if (begin_set[cs_count] == TRUE
6855 && end_set[cs_count] == FALSE) {
6856 cs_table[cs_count].end = downloaded;
6857 end_set[cs_count] = TRUE;
6858 cs_count++;
6859 }
6860 continue;
6861 }
6862 if (critical_sections[cur_cs].begin <= i
6863 && begin_set[cs_count] == FALSE) {
6864 cs_table[cs_count].begin = downloaded;
6865 begin_set[cs_count] = TRUE;
6866 }
6867 break;
6868 }
6869 ahc_download_instr(ahc, i, download_consts);
6870 downloaded++;
6871 }
6872
6873 ahc->num_critical_sections = cs_count;
6874 if (cs_count != 0) {
6875
6876 cs_count *= sizeof(struct cs);
6877 ahc->critical_sections = kmemdup(cs_table, cs_count, GFP_ATOMIC);
6878 if (ahc->critical_sections == NULL)
6879 panic("ahc_loadseq: Could not malloc");
6880 }
6881 ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
6882
6883 if (bootverbose) {
6884 printk(" %d instructions downloaded\n", downloaded);
6885 printk("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n",
6886 ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags);
6887 }
6888 return (0);
6889 }
6890
6891 static int
6892 ahc_check_patch(struct ahc_softc *ahc, const struct patch **start_patch,
6893 u_int start_instr, u_int *skip_addr)
6894 {
6895 const struct patch *cur_patch;
6896 const struct patch *last_patch;
6897 u_int num_patches;
6898
6899 num_patches = ARRAY_SIZE(patches);
6900 last_patch = &patches[num_patches];
6901 cur_patch = *start_patch;
6902
6903 while (cur_patch < last_patch && start_instr == cur_patch->begin) {
6904
6905 if (cur_patch->patch_func(ahc) == 0) {
6906
6907
6908 *skip_addr = start_instr + cur_patch->skip_instr;
6909 cur_patch += cur_patch->skip_patch;
6910 } else {
6911
6912
6913
6914
6915 cur_patch++;
6916 }
6917 }
6918
6919 *start_patch = cur_patch;
6920 if (start_instr < *skip_addr)
6921
6922 return (0);
6923
6924 return (1);
6925 }
6926
6927 static void
6928 ahc_download_instr(struct ahc_softc *ahc, u_int instrptr, uint8_t *dconsts)
6929 {
6930 union ins_formats instr;
6931 struct ins_format1 *fmt1_ins;
6932 struct ins_format3 *fmt3_ins;
6933 u_int opcode;
6934
6935
6936
6937
6938 instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
6939
6940 fmt1_ins = &instr.format1;
6941 fmt3_ins = NULL;
6942
6943
6944 opcode = instr.format1.opcode;
6945 switch (opcode) {
6946 case AIC_OP_JMP:
6947 case AIC_OP_JC:
6948 case AIC_OP_JNC:
6949 case AIC_OP_CALL:
6950 case AIC_OP_JNE:
6951 case AIC_OP_JNZ:
6952 case AIC_OP_JE:
6953 case AIC_OP_JZ:
6954 {
6955 const struct patch *cur_patch;
6956 int address_offset;
6957 u_int address;
6958 u_int skip_addr;
6959 u_int i;
6960
6961 fmt3_ins = &instr.format3;
6962 address_offset = 0;
6963 address = fmt3_ins->address;
6964 cur_patch = patches;
6965 skip_addr = 0;
6966
6967 for (i = 0; i < address;) {
6968
6969 ahc_check_patch(ahc, &cur_patch, i, &skip_addr);
6970
6971 if (skip_addr > i) {
6972 int end_addr;
6973
6974 end_addr = min(address, skip_addr);
6975 address_offset += end_addr - i;
6976 i = skip_addr;
6977 } else {
6978 i++;
6979 }
6980 }
6981 address -= address_offset;
6982 fmt3_ins->address = address;
6983 }
6984 fallthrough;
6985 case AIC_OP_OR:
6986 case AIC_OP_AND:
6987 case AIC_OP_XOR:
6988 case AIC_OP_ADD:
6989 case AIC_OP_ADC:
6990 case AIC_OP_BMOV:
6991 if (fmt1_ins->parity != 0) {
6992 fmt1_ins->immediate = dconsts[fmt1_ins->immediate];
6993 }
6994 fmt1_ins->parity = 0;
6995 if ((ahc->features & AHC_CMD_CHAN) == 0
6996 && opcode == AIC_OP_BMOV) {
6997
6998
6999
7000
7001
7002
7003
7004 if (fmt1_ins->immediate != 1)
7005 panic("%s: BMOV not supported\n",
7006 ahc_name(ahc));
7007 fmt1_ins->opcode = AIC_OP_AND;
7008 fmt1_ins->immediate = 0xff;
7009 }
7010 fallthrough;
7011 case AIC_OP_ROL:
7012 if ((ahc->features & AHC_ULTRA2) != 0) {
7013 int i, count;
7014
7015
7016 for (i = 0, count = 0; i < 31; i++) {
7017 uint32_t mask;
7018
7019 mask = 0x01 << i;
7020 if ((instr.integer & mask) != 0)
7021 count++;
7022 }
7023 if ((count & 0x01) == 0)
7024 instr.format1.parity = 1;
7025 } else {
7026
7027 if (fmt3_ins != NULL) {
7028 instr.integer =
7029 fmt3_ins->immediate
7030 | (fmt3_ins->source << 8)
7031 | (fmt3_ins->address << 16)
7032 | (fmt3_ins->opcode << 25);
7033 } else {
7034 instr.integer =
7035 fmt1_ins->immediate
7036 | (fmt1_ins->source << 8)
7037 | (fmt1_ins->destination << 16)
7038 | (fmt1_ins->ret << 24)
7039 | (fmt1_ins->opcode << 25);
7040 }
7041 }
7042
7043 instr.integer = ahc_htole32(instr.integer);
7044 ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
7045 break;
7046 default:
7047 panic("Unknown opcode encountered in seq program");
7048 break;
7049 }
7050 }
7051
7052 int
7053 ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries,
7054 const char *name, u_int address, u_int value,
7055 u_int *cur_column, u_int wrap_point)
7056 {
7057 int printed;
7058 u_int printed_mask;
7059
7060 if (cur_column != NULL && *cur_column >= wrap_point) {
7061 printk("\n");
7062 *cur_column = 0;
7063 }
7064 printed = printk("%s[0x%x]", name, value);
7065 if (table == NULL) {
7066 printed += printk(" ");
7067 *cur_column += printed;
7068 return (printed);
7069 }
7070 printed_mask = 0;
7071 while (printed_mask != 0xFF) {
7072 int entry;
7073
7074 for (entry = 0; entry < num_entries; entry++) {
7075 if (((value & table[entry].mask)
7076 != table[entry].value)
7077 || ((printed_mask & table[entry].mask)
7078 == table[entry].mask))
7079 continue;
7080
7081 printed += printk("%s%s",
7082 printed_mask == 0 ? ":(" : "|",
7083 table[entry].name);
7084 printed_mask |= table[entry].mask;
7085 break;
7086 }
7087 if (entry >= num_entries)
7088 break;
7089 }
7090 if (printed_mask != 0)
7091 printed += printk(") ");
7092 else
7093 printed += printk(" ");
7094 if (cur_column != NULL)
7095 *cur_column += printed;
7096 return (printed);
7097 }
7098
7099 void
7100 ahc_dump_card_state(struct ahc_softc *ahc)
7101 {
7102 struct scb *scb;
7103 struct scb_tailq *untagged_q;
7104 u_int cur_col;
7105 int paused;
7106 int target;
7107 int maxtarget;
7108 int i;
7109 uint8_t last_phase;
7110 uint8_t qinpos;
7111 uint8_t qintail;
7112 uint8_t qoutpos;
7113 uint8_t scb_index;
7114 uint8_t saved_scbptr;
7115
7116 if (ahc_is_paused(ahc)) {
7117 paused = 1;
7118 } else {
7119 paused = 0;
7120 ahc_pause(ahc);
7121 }
7122
7123 saved_scbptr = ahc_inb(ahc, SCBPTR);
7124 last_phase = ahc_inb(ahc, LASTPHASE);
7125 printk(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
7126 "%s: Dumping Card State %s, at SEQADDR 0x%x\n",
7127 ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg,
7128 ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8));
7129 if (paused)
7130 printk("Card was paused\n");
7131 printk("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
7132 ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
7133 ahc_inb(ahc, ARG_2));
7134 printk("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
7135 ahc_inb(ahc, SCBPTR));
7136 cur_col = 0;
7137 if ((ahc->features & AHC_DT) != 0)
7138 ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50);
7139 ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50);
7140 ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50);
7141 ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50);
7142 ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50);
7143 ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50);
7144 ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50);
7145 ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50);
7146 ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50);
7147 ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50);
7148 ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50);
7149 ahc_sstat1_print(ahc_inb(ahc, SSTAT1), &cur_col, 50);
7150 ahc_sstat2_print(ahc_inb(ahc, SSTAT2), &cur_col, 50);
7151 ahc_sstat3_print(ahc_inb(ahc, SSTAT3), &cur_col, 50);
7152 ahc_simode0_print(ahc_inb(ahc, SIMODE0), &cur_col, 50);
7153 ahc_simode1_print(ahc_inb(ahc, SIMODE1), &cur_col, 50);
7154 ahc_sxfrctl0_print(ahc_inb(ahc, SXFRCTL0), &cur_col, 50);
7155 ahc_dfcntrl_print(ahc_inb(ahc, DFCNTRL), &cur_col, 50);
7156 ahc_dfstatus_print(ahc_inb(ahc, DFSTATUS), &cur_col, 50);
7157 if (cur_col != 0)
7158 printk("\n");
7159 printk("STACK:");
7160 for (i = 0; i < STACK_SIZE; i++)
7161 printk(" 0x%x", ahc_inb(ahc, STACK)|(ahc_inb(ahc, STACK) << 8));
7162 printk("\nSCB count = %d\n", ahc->scb_data->numscbs);
7163 printk("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag);
7164 printk("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB));
7165
7166 printk("QINFIFO entries: ");
7167 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
7168 qinpos = ahc_inb(ahc, SNSCB_QOFF);
7169 ahc_outb(ahc, SNSCB_QOFF, qinpos);
7170 } else
7171 qinpos = ahc_inb(ahc, QINPOS);
7172 qintail = ahc->qinfifonext;
7173 while (qinpos != qintail) {
7174 printk("%d ", ahc->qinfifo[qinpos]);
7175 qinpos++;
7176 }
7177 printk("\n");
7178
7179 printk("Waiting Queue entries: ");
7180 scb_index = ahc_inb(ahc, WAITING_SCBH);
7181 i = 0;
7182 while (scb_index != SCB_LIST_NULL && i++ < 256) {
7183 ahc_outb(ahc, SCBPTR, scb_index);
7184 printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
7185 scb_index = ahc_inb(ahc, SCB_NEXT);
7186 }
7187 printk("\n");
7188
7189 printk("Disconnected Queue entries: ");
7190 scb_index = ahc_inb(ahc, DISCONNECTED_SCBH);
7191 i = 0;
7192 while (scb_index != SCB_LIST_NULL && i++ < 256) {
7193 ahc_outb(ahc, SCBPTR, scb_index);
7194 printk("%d:%d ", scb_index, ahc_inb(ahc, SCB_TAG));
7195 scb_index = ahc_inb(ahc, SCB_NEXT);
7196 }
7197 printk("\n");
7198
7199 ahc_sync_qoutfifo(ahc, BUS_DMASYNC_POSTREAD);
7200 printk("QOUTFIFO entries: ");
7201 qoutpos = ahc->qoutfifonext;
7202 i = 0;
7203 while (ahc->qoutfifo[qoutpos] != SCB_LIST_NULL && i++ < 256) {
7204 printk("%d ", ahc->qoutfifo[qoutpos]);
7205 qoutpos++;
7206 }
7207 printk("\n");
7208
7209 printk("Sequencer Free SCB List: ");
7210 scb_index = ahc_inb(ahc, FREE_SCBH);
7211 i = 0;
7212 while (scb_index != SCB_LIST_NULL && i++ < 256) {
7213 ahc_outb(ahc, SCBPTR, scb_index);
7214 printk("%d ", scb_index);
7215 scb_index = ahc_inb(ahc, SCB_NEXT);
7216 }
7217 printk("\n");
7218
7219 printk("Sequencer SCB Info: ");
7220 for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
7221 ahc_outb(ahc, SCBPTR, i);
7222 cur_col = printk("\n%3d ", i);
7223
7224 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL), &cur_col, 60);
7225 ahc_scb_scsiid_print(ahc_inb(ahc, SCB_SCSIID), &cur_col, 60);
7226 ahc_scb_lun_print(ahc_inb(ahc, SCB_LUN), &cur_col, 60);
7227 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
7228 }
7229 printk("\n");
7230
7231 printk("Pending list: ");
7232 i = 0;
7233 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
7234 if (i++ > 256)
7235 break;
7236 cur_col = printk("\n%3d ", scb->hscb->tag);
7237 ahc_scb_control_print(scb->hscb->control, &cur_col, 60);
7238 ahc_scb_scsiid_print(scb->hscb->scsiid, &cur_col, 60);
7239 ahc_scb_lun_print(scb->hscb->lun, &cur_col, 60);
7240 if ((ahc->flags & AHC_PAGESCBS) == 0) {
7241 ahc_outb(ahc, SCBPTR, scb->hscb->tag);
7242 printk("(");
7243 ahc_scb_control_print(ahc_inb(ahc, SCB_CONTROL),
7244 &cur_col, 60);
7245 ahc_scb_tag_print(ahc_inb(ahc, SCB_TAG), &cur_col, 60);
7246 printk(")");
7247 }
7248 }
7249 printk("\n");
7250
7251 printk("Kernel Free SCB list: ");
7252 i = 0;
7253 SLIST_FOREACH(scb, &ahc->scb_data->free_scbs, links.sle) {
7254 if (i++ > 256)
7255 break;
7256 printk("%d ", scb->hscb->tag);
7257 }
7258 printk("\n");
7259
7260 maxtarget = (ahc->features & (AHC_WIDE|AHC_TWIN)) ? 15 : 7;
7261 for (target = 0; target <= maxtarget; target++) {
7262 untagged_q = &ahc->untagged_queues[target];
7263 if (TAILQ_FIRST(untagged_q) == NULL)
7264 continue;
7265 printk("Untagged Q(%d): ", target);
7266 i = 0;
7267 TAILQ_FOREACH(scb, untagged_q, links.tqe) {
7268 if (i++ > 256)
7269 break;
7270 printk("%d ", scb->hscb->tag);
7271 }
7272 printk("\n");
7273 }
7274
7275 printk("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
7276 ahc_outb(ahc, SCBPTR, saved_scbptr);
7277 if (paused == 0)
7278 ahc_unpause(ahc);
7279 }
7280
7281
7282 #ifdef AHC_TARGET_MODE
7283 cam_status
7284 ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
7285 struct ahc_tmode_tstate **tstate,
7286 struct ahc_tmode_lstate **lstate,
7287 int notfound_failure)
7288 {
7289
7290 if ((ahc->features & AHC_TARGETMODE) == 0)
7291 return (CAM_REQ_INVALID);
7292
7293
7294
7295
7296
7297 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD
7298 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) {
7299 *tstate = NULL;
7300 *lstate = ahc->black_hole;
7301 } else {
7302 u_int max_id;
7303
7304 max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
7305 if (ccb->ccb_h.target_id >= max_id)
7306 return (CAM_TID_INVALID);
7307
7308 if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
7309 return (CAM_LUN_INVALID);
7310
7311 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id];
7312 *lstate = NULL;
7313 if (*tstate != NULL)
7314 *lstate =
7315 (*tstate)->enabled_luns[ccb->ccb_h.target_lun];
7316 }
7317
7318 if (notfound_failure != 0 && *lstate == NULL)
7319 return (CAM_PATH_INVALID);
7320
7321 return (CAM_REQ_CMP);
7322 }
7323
7324 void
7325 ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb)
7326 {
7327 struct ahc_tmode_tstate *tstate;
7328 struct ahc_tmode_lstate *lstate;
7329 struct ccb_en_lun *cel;
7330 cam_status status;
7331 u_long s;
7332 u_int target;
7333 u_int lun;
7334 u_int target_mask;
7335 u_int our_id;
7336 int error;
7337 char channel;
7338
7339 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate,
7340 FALSE);
7341
7342 if (status != CAM_REQ_CMP) {
7343 ccb->ccb_h.status = status;
7344 return;
7345 }
7346
7347 if (cam_sim_bus(sim) == 0)
7348 our_id = ahc->our_id;
7349 else
7350 our_id = ahc->our_id_b;
7351
7352 if (ccb->ccb_h.target_id != our_id) {
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372 if ((ahc->features & AHC_MULTIROLE) != 0) {
7373
7374 if ((ahc->features & AHC_MULTI_TID) != 0
7375 && (ahc->flags & AHC_INITIATORROLE) != 0) {
7376
7377
7378
7379
7380
7381
7382
7383 status = CAM_TID_INVALID;
7384 } else if ((ahc->flags & AHC_INITIATORROLE) != 0
7385 || ahc->enabled_luns > 0) {
7386
7387
7388
7389
7390
7391
7392
7393 status = CAM_TID_INVALID;
7394 }
7395 } else if ((ahc->features & AHC_MULTI_TID) == 0
7396 && ahc->enabled_luns > 0) {
7397
7398 status = CAM_TID_INVALID;
7399 }
7400 }
7401
7402 if (status != CAM_REQ_CMP) {
7403 ccb->ccb_h.status = status;
7404 return;
7405 }
7406
7407
7408
7409
7410
7411 if ((ahc->flags & AHC_TARGETROLE) == 0
7412 && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
7413 u_long s;
7414 ahc_flag saved_flags;
7415
7416 printk("Configuring Target Mode\n");
7417 ahc_lock(ahc, &s);
7418 if (LIST_FIRST(&ahc->pending_scbs) != NULL) {
7419 ccb->ccb_h.status = CAM_BUSY;
7420 ahc_unlock(ahc, &s);
7421 return;
7422 }
7423 saved_flags = ahc->flags;
7424 ahc->flags |= AHC_TARGETROLE;
7425 if ((ahc->features & AHC_MULTIROLE) == 0)
7426 ahc->flags &= ~AHC_INITIATORROLE;
7427 ahc_pause(ahc);
7428 error = ahc_loadseq(ahc);
7429 if (error != 0) {
7430
7431
7432
7433
7434
7435
7436
7437
7438 ahc->flags = saved_flags;
7439 (void)ahc_loadseq(ahc);
7440 ahc_restart(ahc);
7441 ahc_unlock(ahc, &s);
7442 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
7443 return;
7444 }
7445 ahc_restart(ahc);
7446 ahc_unlock(ahc, &s);
7447 }
7448 cel = &ccb->cel;
7449 target = ccb->ccb_h.target_id;
7450 lun = ccb->ccb_h.target_lun;
7451 channel = SIM_CHANNEL(ahc, sim);
7452 target_mask = 0x01 << target;
7453 if (channel == 'B')
7454 target_mask <<= 8;
7455
7456 if (cel->enable != 0) {
7457 u_int scsiseq;
7458
7459
7460 if (lstate != NULL) {
7461 xpt_print_path(ccb->ccb_h.path);
7462 printk("Lun already enabled\n");
7463 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
7464 return;
7465 }
7466
7467 if (cel->grp6_len != 0
7468 || cel->grp7_len != 0) {
7469
7470
7471
7472
7473 ccb->ccb_h.status = CAM_REQ_INVALID;
7474 printk("Non-zero Group Codes\n");
7475 return;
7476 }
7477
7478
7479
7480
7481
7482 if (target != CAM_TARGET_WILDCARD && tstate == NULL) {
7483 tstate = ahc_alloc_tstate(ahc, target, channel);
7484 if (tstate == NULL) {
7485 xpt_print_path(ccb->ccb_h.path);
7486 printk("Couldn't allocate tstate\n");
7487 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7488 return;
7489 }
7490 }
7491 lstate = kzalloc(sizeof(*lstate), GFP_ATOMIC);
7492 if (lstate == NULL) {
7493 xpt_print_path(ccb->ccb_h.path);
7494 printk("Couldn't allocate lstate\n");
7495 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7496 return;
7497 }
7498 status = xpt_create_path(&lstate->path, NULL,
7499 xpt_path_path_id(ccb->ccb_h.path),
7500 xpt_path_target_id(ccb->ccb_h.path),
7501 xpt_path_lun_id(ccb->ccb_h.path));
7502 if (status != CAM_REQ_CMP) {
7503 kfree(lstate);
7504 xpt_print_path(ccb->ccb_h.path);
7505 printk("Couldn't allocate path\n");
7506 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
7507 return;
7508 }
7509 SLIST_INIT(&lstate->accept_tios);
7510 SLIST_INIT(&lstate->immed_notifies);
7511 ahc_lock(ahc, &s);
7512 ahc_pause(ahc);
7513 if (target != CAM_TARGET_WILDCARD) {
7514 tstate->enabled_luns[lun] = lstate;
7515 ahc->enabled_luns++;
7516
7517 if ((ahc->features & AHC_MULTI_TID) != 0) {
7518 u_int targid_mask;
7519
7520 targid_mask = ahc_inb(ahc, TARGID)
7521 | (ahc_inb(ahc, TARGID + 1) << 8);
7522
7523 targid_mask |= target_mask;
7524 ahc_outb(ahc, TARGID, targid_mask);
7525 ahc_outb(ahc, TARGID+1, (targid_mask >> 8));
7526 ahc_update_scsiid(ahc, targid_mask);
7527 } else {
7528 u_int our_id;
7529 char channel;
7530
7531 channel = SIM_CHANNEL(ahc, sim);
7532 our_id = SIM_SCSI_ID(ahc, sim);
7533
7534
7535
7536
7537
7538 if (target != our_id) {
7539 u_int sblkctl;
7540 char cur_channel;
7541 int swap;
7542
7543 sblkctl = ahc_inb(ahc, SBLKCTL);
7544 cur_channel = (sblkctl & SELBUSB)
7545 ? 'B' : 'A';
7546 if ((ahc->features & AHC_TWIN) == 0)
7547 cur_channel = 'A';
7548 swap = cur_channel != channel;
7549 if (channel == 'A')
7550 ahc->our_id = target;
7551 else
7552 ahc->our_id_b = target;
7553
7554 if (swap)
7555 ahc_outb(ahc, SBLKCTL,
7556 sblkctl ^ SELBUSB);
7557
7558 ahc_outb(ahc, SCSIID, target);
7559
7560 if (swap)
7561 ahc_outb(ahc, SBLKCTL, sblkctl);
7562 }
7563 }
7564 } else
7565 ahc->black_hole = lstate;
7566
7567 if (ahc->black_hole != NULL && ahc->enabled_luns > 0) {
7568 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
7569 scsiseq |= ENSELI;
7570 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
7571 scsiseq = ahc_inb(ahc, SCSISEQ);
7572 scsiseq |= ENSELI;
7573 ahc_outb(ahc, SCSISEQ, scsiseq);
7574 }
7575 ahc_unpause(ahc);
7576 ahc_unlock(ahc, &s);
7577 ccb->ccb_h.status = CAM_REQ_CMP;
7578 xpt_print_path(ccb->ccb_h.path);
7579 printk("Lun now enabled for target mode\n");
7580 } else {
7581 struct scb *scb;
7582 int i, empty;
7583
7584 if (lstate == NULL) {
7585 ccb->ccb_h.status = CAM_LUN_INVALID;
7586 return;
7587 }
7588
7589 ahc_lock(ahc, &s);
7590
7591 ccb->ccb_h.status = CAM_REQ_CMP;
7592 LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
7593 struct ccb_hdr *ccbh;
7594
7595 ccbh = &scb->io_ctx->ccb_h;
7596 if (ccbh->func_code == XPT_CONT_TARGET_IO
7597 && !xpt_path_comp(ccbh->path, ccb->ccb_h.path)){
7598 printk("CTIO pending\n");
7599 ccb->ccb_h.status = CAM_REQ_INVALID;
7600 ahc_unlock(ahc, &s);
7601 return;
7602 }
7603 }
7604
7605 if (SLIST_FIRST(&lstate->accept_tios) != NULL) {
7606 printk("ATIOs pending\n");
7607 ccb->ccb_h.status = CAM_REQ_INVALID;
7608 }
7609
7610 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) {
7611 printk("INOTs pending\n");
7612 ccb->ccb_h.status = CAM_REQ_INVALID;
7613 }
7614
7615 if (ccb->ccb_h.status != CAM_REQ_CMP) {
7616 ahc_unlock(ahc, &s);
7617 return;
7618 }
7619
7620 xpt_print_path(ccb->ccb_h.path);
7621 printk("Target mode disabled\n");
7622 xpt_free_path(lstate->path);
7623 kfree(lstate);
7624
7625 ahc_pause(ahc);
7626
7627 if (target != CAM_TARGET_WILDCARD) {
7628 tstate->enabled_luns[lun] = NULL;
7629 ahc->enabled_luns--;
7630 for (empty = 1, i = 0; i < 8; i++)
7631 if (tstate->enabled_luns[i] != NULL) {
7632 empty = 0;
7633 break;
7634 }
7635
7636 if (empty) {
7637 ahc_free_tstate(ahc, target, channel,
7638 FALSE);
7639 if (ahc->features & AHC_MULTI_TID) {
7640 u_int targid_mask;
7641
7642 targid_mask = ahc_inb(ahc, TARGID)
7643 | (ahc_inb(ahc, TARGID + 1)
7644 << 8);
7645
7646 targid_mask &= ~target_mask;
7647 ahc_outb(ahc, TARGID, targid_mask);
7648 ahc_outb(ahc, TARGID+1,
7649 (targid_mask >> 8));
7650 ahc_update_scsiid(ahc, targid_mask);
7651 }
7652 }
7653 } else {
7654
7655 ahc->black_hole = NULL;
7656
7657
7658
7659
7660
7661 empty = TRUE;
7662 }
7663 if (ahc->enabled_luns == 0) {
7664
7665 u_int scsiseq;
7666
7667 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE);
7668 scsiseq &= ~ENSELI;
7669 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq);
7670 scsiseq = ahc_inb(ahc, SCSISEQ);
7671 scsiseq &= ~ENSELI;
7672 ahc_outb(ahc, SCSISEQ, scsiseq);
7673
7674 if ((ahc->features & AHC_MULTIROLE) == 0) {
7675 printk("Configuring Initiator Mode\n");
7676 ahc->flags &= ~AHC_TARGETROLE;
7677 ahc->flags |= AHC_INITIATORROLE;
7678
7679
7680
7681
7682 (void)ahc_loadseq(ahc);
7683 ahc_restart(ahc);
7684
7685
7686
7687
7688 }
7689 }
7690 ahc_unpause(ahc);
7691 ahc_unlock(ahc, &s);
7692 }
7693 }
7694
7695 static void
7696 ahc_update_scsiid(struct ahc_softc *ahc, u_int targid_mask)
7697 {
7698 u_int scsiid_mask;
7699 u_int scsiid;
7700
7701 if ((ahc->features & AHC_MULTI_TID) == 0)
7702 panic("ahc_update_scsiid called on non-multitid unit\n");
7703
7704
7705
7706
7707
7708
7709
7710 if ((ahc->features & AHC_ULTRA2) != 0)
7711 scsiid = ahc_inb(ahc, SCSIID_ULTRA2);
7712 else
7713 scsiid = ahc_inb(ahc, SCSIID);
7714 scsiid_mask = 0x1 << (scsiid & OID);
7715 if ((targid_mask & scsiid_mask) == 0) {
7716 u_int our_id;
7717
7718
7719 our_id = ffs(targid_mask);
7720 if (our_id == 0)
7721 our_id = ahc->our_id;
7722 else
7723 our_id--;
7724 scsiid &= TID;
7725 scsiid |= our_id;
7726 }
7727 if ((ahc->features & AHC_ULTRA2) != 0)
7728 ahc_outb(ahc, SCSIID_ULTRA2, scsiid);
7729 else
7730 ahc_outb(ahc, SCSIID, scsiid);
7731 }
7732
7733 static void
7734 ahc_run_tqinfifo(struct ahc_softc *ahc, int paused)
7735 {
7736 struct target_cmd *cmd;
7737
7738
7739
7740
7741
7742
7743 if ((ahc->features & AHC_AUTOPAUSE) != 0)
7744 paused = TRUE;
7745
7746 ahc_sync_tqinfifo(ahc, BUS_DMASYNC_POSTREAD);
7747 while ((cmd = &ahc->targetcmds[ahc->tqinfifonext])->cmd_valid != 0) {
7748
7749
7750
7751
7752
7753 if (ahc_handle_target_cmd(ahc, cmd) != 0)
7754 break;
7755
7756 cmd->cmd_valid = 0;
7757 ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
7758 ahc->shared_data_dmamap,
7759 ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
7760 sizeof(struct target_cmd),
7761 BUS_DMASYNC_PREREAD);
7762 ahc->tqinfifonext++;
7763
7764
7765
7766
7767
7768 if ((ahc->tqinfifonext & (HOST_TQINPOS - 1)) == 1) {
7769 if ((ahc->features & AHC_HS_MAILBOX) != 0) {
7770 u_int hs_mailbox;
7771
7772 hs_mailbox = ahc_inb(ahc, HS_MAILBOX);
7773 hs_mailbox &= ~HOST_TQINPOS;
7774 hs_mailbox |= ahc->tqinfifonext & HOST_TQINPOS;
7775 ahc_outb(ahc, HS_MAILBOX, hs_mailbox);
7776 } else {
7777 if (!paused)
7778 ahc_pause(ahc);
7779 ahc_outb(ahc, KERNEL_TQINPOS,
7780 ahc->tqinfifonext & HOST_TQINPOS);
7781 if (!paused)
7782 ahc_unpause(ahc);
7783 }
7784 }
7785 }
7786 }
7787
7788 static int
7789 ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd)
7790 {
7791 struct ahc_tmode_tstate *tstate;
7792 struct ahc_tmode_lstate *lstate;
7793 struct ccb_accept_tio *atio;
7794 uint8_t *byte;
7795 int initiator;
7796 int target;
7797 int lun;
7798
7799 initiator = SCSIID_TARGET(ahc, cmd->scsiid);
7800 target = SCSIID_OUR_ID(cmd->scsiid);
7801 lun = (cmd->identify & MSG_IDENTIFY_LUNMASK);
7802
7803 byte = cmd->bytes;
7804 tstate = ahc->enabled_targets[target];
7805 lstate = NULL;
7806 if (tstate != NULL)
7807 lstate = tstate->enabled_luns[lun];
7808
7809
7810
7811
7812 if (lstate == NULL)
7813 lstate = ahc->black_hole;
7814
7815 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios);
7816 if (atio == NULL) {
7817 ahc->flags |= AHC_TQINFIFO_BLOCKED;
7818
7819
7820
7821 if (bootverbose)
7822 printk("%s: ATIOs exhausted\n", ahc_name(ahc));
7823 return (1);
7824 } else
7825 ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
7826 #if 0
7827 printk("Incoming command from %d for %d:%d%s\n",
7828 initiator, target, lun,
7829 lstate == ahc->black_hole ? "(Black Holed)" : "");
7830 #endif
7831 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle);
7832
7833 if (lstate == ahc->black_hole) {
7834
7835 atio->ccb_h.target_id = target;
7836 atio->ccb_h.target_lun = lun;
7837 }
7838
7839
7840
7841
7842
7843 atio->sense_len = 0;
7844 atio->init_id = initiator;
7845 if (byte[0] != 0xFF) {
7846
7847 atio->tag_action = *byte++;
7848 atio->tag_id = *byte++;
7849 atio->ccb_h.flags = CAM_TAG_ACTION_VALID;
7850 } else {
7851 atio->ccb_h.flags = 0;
7852 }
7853 byte++;
7854
7855
7856 switch (*byte >> CMD_GROUP_CODE_SHIFT) {
7857 case 0:
7858 atio->cdb_len = 6;
7859 break;
7860 case 1:
7861 case 2:
7862 atio->cdb_len = 10;
7863 break;
7864 case 4:
7865 atio->cdb_len = 16;
7866 break;
7867 case 5:
7868 atio->cdb_len = 12;
7869 break;
7870 case 3:
7871 default:
7872
7873 atio->cdb_len = 1;
7874 printk("Reserved or VU command code type encountered\n");
7875 break;
7876 }
7877
7878 memcpy(atio->cdb_io.cdb_bytes, byte, atio->cdb_len);
7879
7880 atio->ccb_h.status |= CAM_CDB_RECVD;
7881
7882 if ((cmd->identify & MSG_IDENTIFY_DISCFLAG) == 0) {
7883
7884
7885
7886
7887
7888
7889 #if 0
7890 printk("Received Immediate Command %d:%d:%d - %p\n",
7891 initiator, target, lun, ahc->pending_device);
7892 #endif
7893 ahc->pending_device = lstate;
7894 ahc_freeze_ccb((union ccb *)atio);
7895 atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
7896 }
7897 xpt_done((union ccb*)atio);
7898 return (0);
7899 }
7900
7901 #endif