1 /* 2 ********************************************************************* 3 * FILE NAME : amd.c 4 * BY : C.L. Huang (ching@tekram.com.tw) 5 * Erich Chen (erich@tekram.com.tw) 6 * Description: Device Driver for the amd53c974 PCI Bus Master 7 * SCSI Host adapter found on cards such as 8 * the Tekram DC-390(T). 9 * (C)Copyright 1995-1999 Tekram Technology Co., Ltd. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 ********************************************************************* 33 * $FreeBSD: src/sys/pci/amd.c,v 1.3.2.2 2001/06/02 04:32:50 nyan Exp $ 34 * $DragonFly: src/sys/dev/disk/amd/amd.c,v 1.9 2005/10/12 17:35:50 dillon Exp $ 35 */ 36 37 /* 38 ********************************************************************* 39 * HISTORY: 40 * 41 * REV# DATE NAME DESCRIPTION 42 * 1.00 07/02/96 CLH First release for RELEASE-2.1.0 43 * 1.01 08/20/96 CLH Update for RELEASE-2.1.5 44 * 1.02 11/06/96 CLH Fixed more than 1 LUN scanning 45 * 1.03 12/20/96 CLH Modify to support 2.2-ALPHA 46 * 1.04 12/26/97 CLH Modify to support RELEASE-2.2.5 47 * 1.05 01/01/99 ERICH CHEN Modify to support RELEASE-3.0.x (CAM) 48 ********************************************************************* 49 */ 50 51 /* #define AMD_DEBUG0 */ 52 /* #define AMD_DEBUG_SCSI_PHASE */ 53 54 #include <sys/param.h> 55 56 #include <sys/systm.h> 57 #include <sys/malloc.h> 58 #include <sys/queue.h> 59 #include <sys/buf.h> 60 #include <sys/kernel.h> 61 #include <sys/thread2.h> 62 63 #include <vm/vm.h> 64 #include <vm/pmap.h> 65 66 #include <machine/bus_pio.h> 67 #include <machine/bus.h> 68 #include <machine/clock.h> 69 #include <machine/resource.h> 70 #include <sys/bus.h> 71 #include <sys/rman.h> 72 73 #include <bus/cam/cam.h> 74 #include <bus/cam/cam_ccb.h> 75 #include <bus/cam/cam_sim.h> 76 #include <bus/cam/cam_xpt_sim.h> 77 #include <bus/cam/cam_debug.h> 78 79 #include <bus/cam/scsi/scsi_all.h> 80 #include <bus/cam/scsi/scsi_message.h> 81 82 #include <bus/pci/pcivar.h> 83 #include <bus/pci/pcireg.h> 84 #include "amd.h" 85 86 #define PCI_DEVICE_ID_AMD53C974 0x20201022ul 87 #define PCI_BASE_ADDR0 0x10 88 89 typedef u_int (phase_handler_t)(struct amd_softc *, struct amd_srb *, u_int); 90 typedef phase_handler_t *phase_handler_func_t; 91 92 static void amd_intr(void *vamd); 93 static int amdstart(struct amd_softc *amd, struct amd_srb * pSRB); 94 static phase_handler_t amd_NopPhase; 95 96 static phase_handler_t amd_DataOutPhase0; 97 static phase_handler_t amd_DataInPhase0; 98 #define amd_CommandPhase0 amd_NopPhase 99 static phase_handler_t amd_StatusPhase0; 100 static phase_handler_t amd_MsgOutPhase0; 101 static phase_handler_t amd_MsgInPhase0; 102 static phase_handler_t amd_DataOutPhase1; 103 static phase_handler_t amd_DataInPhase1; 104 static phase_handler_t amd_CommandPhase1; 105 static phase_handler_t amd_StatusPhase1; 106 static phase_handler_t amd_MsgOutPhase1; 107 static phase_handler_t amd_MsgInPhase1; 108 109 static void amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb); 110 static int amdparsemsg(struct amd_softc *amd); 111 static int amdhandlemsgreject(struct amd_softc *amd); 112 static void amdconstructsdtr(struct amd_softc *amd, 113 u_int period, u_int offset); 114 static u_int amdfindclockrate(struct amd_softc *amd, u_int *period); 115 static int amdsentmsg(struct amd_softc *amd, u_int msgtype, int full); 116 117 static void DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int dir); 118 static void amd_Disconnect(struct amd_softc *amd); 119 static void amd_Reselect(struct amd_softc *amd); 120 static void SRBdone(struct amd_softc *amd, struct amd_srb *pSRB); 121 static void amd_ScsiRstDetect(struct amd_softc *amd); 122 static void amd_ResetSCSIBus(struct amd_softc *amd); 123 static void RequestSense(struct amd_softc *amd, struct amd_srb *pSRB); 124 static void amd_InvalidCmd(struct amd_softc *amd); 125 126 #if 0 127 static void amd_timeout(void *arg1); 128 static void amd_reset(struct amd_softc *amd); 129 #endif 130 static u_int8_t * phystovirt(struct amd_srb *pSRB, u_int32_t xferCnt); 131 132 void amd_linkSRB(struct amd_softc *amd); 133 static int amd_init(device_t); 134 static void amd_load_defaults(struct amd_softc *amd); 135 static void amd_load_eeprom_or_defaults(struct amd_softc *amd); 136 static int amd_EEpromInDO(struct amd_softc *amd); 137 static u_int16_t EEpromGetData1(struct amd_softc *amd); 138 static void amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval); 139 static void amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry); 140 static void amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd); 141 static void amd_ReadEEprom(struct amd_softc *amd); 142 143 static int amd_probe(device_t); 144 static int amd_attach(device_t); 145 static void amdcompletematch(struct amd_softc *amd, target_id_t target, 146 lun_id_t lun, u_int tag, struct srb_queue *queue, 147 cam_status status); 148 static void amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate, 149 u_int period, u_int offset, u_int type); 150 static void amdsettags(struct amd_softc *amd, u_int target, int tagenb); 151 152 static __inline void amd_clear_msg_state(struct amd_softc *amd); 153 154 static __inline void 155 amd_clear_msg_state(struct amd_softc *amd) 156 { 157 amd->msgout_len = 0; 158 amd->msgout_index = 0; 159 amd->msgin_index = 0; 160 } 161 162 /* CAM SIM entry points */ 163 #define ccb_srb_ptr spriv_ptr0 164 #define ccb_amd_ptr spriv_ptr1 165 static void amd_action(struct cam_sim *sim, union ccb *ccb); 166 static void amd_poll(struct cam_sim *sim); 167 168 /* 169 * State engine function tables indexed by SCSI phase number 170 */ 171 phase_handler_func_t amd_SCSI_phase0[] = { 172 amd_DataOutPhase0, 173 amd_DataInPhase0, 174 amd_CommandPhase0, 175 amd_StatusPhase0, 176 amd_NopPhase, 177 amd_NopPhase, 178 amd_MsgOutPhase0, 179 amd_MsgInPhase0 180 }; 181 182 phase_handler_func_t amd_SCSI_phase1[] = { 183 amd_DataOutPhase1, 184 amd_DataInPhase1, 185 amd_CommandPhase1, 186 amd_StatusPhase1, 187 amd_NopPhase, 188 amd_NopPhase, 189 amd_MsgOutPhase1, 190 amd_MsgInPhase1 191 }; 192 193 /* 194 * EEProm/BIOS negotiation periods 195 */ 196 u_int8_t eeprom_period[] = { 197 25, /* 10.0MHz */ 198 32, /* 8.0MHz */ 199 38, /* 6.6MHz */ 200 44, /* 5.7MHz */ 201 50, /* 5.0MHz */ 202 63, /* 4.0MHz */ 203 83, /* 3.0MHz */ 204 125 /* 2.0MHz */ 205 }; 206 207 /* 208 * chip clock setting to SCSI specified sync parameter table. 209 */ 210 u_int8_t tinfo_sync_period[] = { 211 25, /* 10.0 */ 212 32, /* 8.0 */ 213 38, /* 6.6 */ 214 44, /* 5.7 */ 215 50, /* 5.0 */ 216 57, /* 4.4 */ 217 63, /* 4.0 */ 218 70, /* 3.6 */ 219 76, /* 3.3 */ 220 83 /* 3.0 */ 221 }; 222 223 static __inline struct amd_srb * 224 amdgetsrb(struct amd_softc * amd) 225 { 226 struct amd_srb * pSRB; 227 228 crit_enter(); 229 pSRB = TAILQ_FIRST(&amd->free_srbs); 230 if (pSRB) 231 TAILQ_REMOVE(&amd->free_srbs, pSRB, links); 232 crit_exit(); 233 return (pSRB); 234 } 235 236 static void 237 amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb) 238 { 239 struct scsi_request_sense sense_cmd; 240 struct ccb_scsiio *csio; 241 u_int8_t *cdb; 242 u_int cdb_len; 243 244 csio = &srb->pccb->csio; 245 246 if (srb->SRBFlag & AUTO_REQSENSE) { 247 sense_cmd.opcode = REQUEST_SENSE; 248 sense_cmd.byte2 = srb->pccb->ccb_h.target_lun << 5; 249 sense_cmd.unused[0] = 0; 250 sense_cmd.unused[1] = 0; 251 sense_cmd.length = csio->sense_len; 252 sense_cmd.control = 0; 253 cdb = &sense_cmd.opcode; 254 cdb_len = sizeof(sense_cmd); 255 } else { 256 cdb = &srb->CmdBlock[0]; 257 cdb_len = srb->ScsiCmdLen; 258 } 259 amd_write8_multi(amd, SCSIFIFOREG, cdb, cdb_len); 260 } 261 262 /* 263 * Attempt to start a waiting transaction. Interrupts must be disabled 264 * upon entry to this function. 265 */ 266 static void 267 amdrunwaiting(struct amd_softc *amd) { 268 struct amd_srb *srb; 269 270 if (amd->last_phase != SCSI_BUS_FREE) 271 return; 272 273 srb = TAILQ_FIRST(&amd->waiting_srbs); 274 if (srb == NULL) 275 return; 276 277 if (amdstart(amd, srb) == 0) { 278 TAILQ_REMOVE(&amd->waiting_srbs, srb, links); 279 TAILQ_INSERT_HEAD(&amd->running_srbs, srb, links); 280 } 281 } 282 283 static void 284 amdexecutesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 285 { 286 struct amd_srb *srb; 287 union ccb *ccb; 288 struct amd_softc *amd; 289 290 srb = (struct amd_srb *)arg; 291 ccb = srb->pccb; 292 amd = (struct amd_softc *)ccb->ccb_h.ccb_amd_ptr; 293 294 if (error != 0) { 295 if (error != EFBIG) 296 printf("amd%d: Unexepected error 0x%x returned from " 297 "bus_dmamap_load\n", amd->unit, error); 298 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 299 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 300 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 301 } 302 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links); 303 xpt_done(ccb); 304 return; 305 } 306 307 if (nseg != 0) { 308 struct amd_sg *sg; 309 bus_dma_segment_t *end_seg; 310 bus_dmasync_op_t op; 311 312 end_seg = dm_segs + nseg; 313 314 /* Copy the segments into our SG list */ 315 srb->pSGlist = &srb->SGsegment[0]; 316 sg = srb->pSGlist; 317 while (dm_segs < end_seg) { 318 sg->SGXLen = dm_segs->ds_len; 319 sg->SGXPtr = dm_segs->ds_addr; 320 sg++; 321 dm_segs++; 322 } 323 324 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 325 op = BUS_DMASYNC_PREREAD; 326 else 327 op = BUS_DMASYNC_PREWRITE; 328 329 bus_dmamap_sync(amd->buffer_dmat, srb->dmamap, op); 330 331 } 332 srb->SGcount = nseg; 333 srb->SGIndex = 0; 334 srb->AdaptStatus = 0; 335 srb->TargetStatus = 0; 336 srb->MsgCnt = 0; 337 srb->SRBStatus = 0; 338 srb->SRBFlag = 0; 339 srb->SRBState = 0; 340 srb->TotalXferredLen = 0; 341 srb->SGPhysAddr = 0; 342 srb->SGToBeXferLen = 0; 343 srb->EndMessage = 0; 344 345 crit_enter(); 346 347 /* 348 * Last time we need to check if this CCB needs to 349 * be aborted. 350 */ 351 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 352 if (nseg != 0) 353 bus_dmamap_unload(amd->buffer_dmat, srb->dmamap); 354 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links); 355 xpt_done(ccb); 356 crit_exit(); 357 return; 358 } 359 ccb->ccb_h.status |= CAM_SIM_QUEUED; 360 #if 0 361 /* XXX Need a timeout handler */ 362 callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000, 363 amdtimeout, srb); 364 #endif 365 TAILQ_INSERT_TAIL(&amd->waiting_srbs, srb, links); 366 amdrunwaiting(amd); 367 crit_exit(); 368 } 369 370 static void 371 amd_action(struct cam_sim * psim, union ccb * pccb) 372 { 373 struct amd_softc * amd; 374 u_int target_id, target_lun; 375 376 CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("amd_action\n")); 377 378 amd = (struct amd_softc *) cam_sim_softc(psim); 379 target_id = pccb->ccb_h.target_id; 380 target_lun = pccb->ccb_h.target_lun; 381 382 switch (pccb->ccb_h.func_code) { 383 case XPT_SCSI_IO: 384 { 385 struct amd_srb * pSRB; 386 struct ccb_scsiio *pcsio; 387 388 pcsio = &pccb->csio; 389 390 /* 391 * Assign an SRB and connect it with this ccb. 392 */ 393 pSRB = amdgetsrb(amd); 394 395 if (!pSRB) { 396 /* Freeze SIMQ */ 397 pccb->ccb_h.status = CAM_RESRC_UNAVAIL; 398 xpt_done(pccb); 399 return; 400 } 401 pSRB->pccb = pccb; 402 pccb->ccb_h.ccb_srb_ptr = pSRB; 403 pccb->ccb_h.ccb_amd_ptr = amd; 404 pSRB->ScsiCmdLen = pcsio->cdb_len; 405 bcopy(pcsio->cdb_io.cdb_bytes, pSRB->CmdBlock, pcsio->cdb_len); 406 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 407 if ((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { 408 /* 409 * We've been given a pointer 410 * to a single buffer. 411 */ 412 if ((pccb->ccb_h.flags & CAM_DATA_PHYS) == 0) { 413 int error; 414 415 crit_enter(); 416 error = 417 bus_dmamap_load(amd->buffer_dmat, 418 pSRB->dmamap, 419 pcsio->data_ptr, 420 pcsio->dxfer_len, 421 amdexecutesrb, 422 pSRB, /*flags*/0); 423 if (error == EINPROGRESS) { 424 /* 425 * So as to maintain 426 * ordering, freeze the 427 * controller queue 428 * until our mapping is 429 * returned. 430 */ 431 xpt_freeze_simq(amd->psim, 1); 432 pccb->ccb_h.status |= 433 CAM_RELEASE_SIMQ; 434 } 435 crit_exit(); 436 } else { 437 struct bus_dma_segment seg; 438 439 /* Pointer to physical buffer */ 440 seg.ds_addr = 441 (bus_addr_t)pcsio->data_ptr; 442 seg.ds_len = pcsio->dxfer_len; 443 amdexecutesrb(pSRB, &seg, 1, 0); 444 } 445 } else { 446 struct bus_dma_segment *segs; 447 448 if ((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0 449 || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) { 450 TAILQ_INSERT_HEAD(&amd->free_srbs, 451 pSRB, links); 452 pccb->ccb_h.status = CAM_PROVIDE_FAIL; 453 xpt_done(pccb); 454 return; 455 } 456 457 /* Just use the segments provided */ 458 segs = 459 (struct bus_dma_segment *)pcsio->data_ptr; 460 amdexecutesrb(pSRB, segs, pcsio->sglist_cnt, 0); 461 } 462 } else 463 amdexecutesrb(pSRB, NULL, 0, 0); 464 break; 465 } 466 case XPT_PATH_INQ: 467 { 468 struct ccb_pathinq *cpi = &pccb->cpi; 469 470 cpi->version_num = 1; 471 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE; 472 cpi->target_sprt = 0; 473 cpi->hba_misc = 0; 474 cpi->hba_eng_cnt = 0; 475 cpi->max_target = 7; 476 cpi->max_lun = amd->max_lun; /* 7 or 0 */ 477 cpi->initiator_id = amd->AdaptSCSIID; 478 cpi->bus_id = cam_sim_bus(psim); 479 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 480 strncpy(cpi->hba_vid, "TRM-AMD", HBA_IDLEN); 481 strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); 482 cpi->unit_number = cam_sim_unit(psim); 483 cpi->ccb_h.status = CAM_REQ_CMP; 484 xpt_done(pccb); 485 break; 486 } 487 case XPT_ABORT: 488 pccb->ccb_h.status = CAM_REQ_INVALID; 489 xpt_done(pccb); 490 break; 491 case XPT_RESET_BUS: 492 { 493 494 int i; 495 496 amd_ResetSCSIBus(amd); 497 amd->ACBFlag = 0; 498 499 for (i = 0; i < 500; i++) { 500 DELAY(1000); /* Wait until our interrupt 501 * handler sees it */ 502 } 503 504 pccb->ccb_h.status = CAM_REQ_CMP; 505 xpt_done(pccb); 506 break; 507 } 508 case XPT_RESET_DEV: 509 pccb->ccb_h.status = CAM_REQ_INVALID; 510 xpt_done(pccb); 511 break; 512 case XPT_TERM_IO: 513 pccb->ccb_h.status = CAM_REQ_INVALID; 514 xpt_done(pccb); 515 case XPT_GET_TRAN_SETTINGS: 516 { 517 struct ccb_trans_settings *cts; 518 struct amd_target_info *targ_info; 519 struct amd_transinfo *tinfo; 520 521 cts = &pccb->cts; 522 crit_enter(); 523 targ_info = &amd->tinfo[target_id]; 524 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { 525 /* current transfer settings */ 526 if (targ_info->disc_tag & AMD_CUR_DISCENB) { 527 cts->flags = CCB_TRANS_DISC_ENB; 528 } else { 529 cts->flags = 0; /* no tag & disconnect */ 530 } 531 if (targ_info->disc_tag & AMD_CUR_TAGENB) { 532 cts->flags |= CCB_TRANS_TAG_ENB; 533 } 534 tinfo = &targ_info->current; 535 } else { 536 /* default(user) transfer settings */ 537 if (targ_info->disc_tag & AMD_USR_DISCENB) { 538 cts->flags = CCB_TRANS_DISC_ENB; 539 } else { 540 cts->flags = 0; 541 } 542 if (targ_info->disc_tag & AMD_USR_TAGENB) { 543 cts->flags |= CCB_TRANS_TAG_ENB; 544 } 545 tinfo = &targ_info->user; 546 } 547 548 cts->sync_period = tinfo->period; 549 cts->sync_offset = tinfo->offset; 550 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 551 crit_exit(); 552 cts->valid = CCB_TRANS_SYNC_RATE_VALID 553 | CCB_TRANS_SYNC_OFFSET_VALID 554 | CCB_TRANS_BUS_WIDTH_VALID 555 | CCB_TRANS_DISC_VALID 556 | CCB_TRANS_TQ_VALID; 557 pccb->ccb_h.status = CAM_REQ_CMP; 558 xpt_done(pccb); 559 break; 560 } 561 case XPT_SET_TRAN_SETTINGS: 562 { 563 struct ccb_trans_settings *cts; 564 struct amd_target_info *targ_info; 565 u_int update_type; 566 int last_entry; 567 568 cts = &pccb->cts; 569 update_type = 0; 570 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { 571 update_type |= AMD_TRANS_GOAL; 572 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 573 update_type |= AMD_TRANS_USER; 574 } 575 if (update_type == 0 576 || update_type == (AMD_TRANS_USER|AMD_TRANS_GOAL)) { 577 cts->ccb_h.status = CAM_REQ_INVALID; 578 xpt_done(pccb); 579 } 580 581 crit_enter(); 582 targ_info = &amd->tinfo[target_id]; 583 584 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) { 585 if (update_type & AMD_TRANS_GOAL) { 586 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) { 587 targ_info->disc_tag |= AMD_CUR_DISCENB; 588 } else { 589 targ_info->disc_tag &= ~AMD_CUR_DISCENB; 590 } 591 } 592 if (update_type & AMD_TRANS_USER) { 593 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) { 594 targ_info->disc_tag |= AMD_USR_DISCENB; 595 } else { 596 targ_info->disc_tag &= ~AMD_USR_DISCENB; 597 } 598 } 599 } 600 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) { 601 if (update_type & AMD_TRANS_GOAL) { 602 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) { 603 targ_info->disc_tag |= AMD_CUR_TAGENB; 604 } else { 605 targ_info->disc_tag &= ~AMD_CUR_TAGENB; 606 } 607 } 608 if (update_type & AMD_TRANS_USER) { 609 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) { 610 targ_info->disc_tag |= AMD_USR_TAGENB; 611 } else { 612 targ_info->disc_tag &= ~AMD_USR_TAGENB; 613 } 614 } 615 } 616 617 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) { 618 if (update_type & AMD_TRANS_GOAL) 619 cts->sync_offset = targ_info->goal.offset; 620 else 621 cts->sync_offset = targ_info->user.offset; 622 } 623 624 if (cts->sync_offset > AMD_MAX_SYNC_OFFSET) 625 cts->sync_offset = AMD_MAX_SYNC_OFFSET; 626 627 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) { 628 if (update_type & AMD_TRANS_GOAL) 629 cts->sync_period = targ_info->goal.period; 630 else 631 cts->sync_period = targ_info->user.period; 632 } 633 634 last_entry = sizeof(tinfo_sync_period) - 1; 635 if ((cts->sync_period != 0) 636 && (cts->sync_period < tinfo_sync_period[0])) 637 cts->sync_period = tinfo_sync_period[0]; 638 if (cts->sync_period > tinfo_sync_period[last_entry]) 639 cts->sync_period = 0; 640 if (cts->sync_offset == 0) 641 cts->sync_period = 0; 642 643 if ((update_type & AMD_TRANS_USER) != 0) { 644 targ_info->user.period = cts->sync_period; 645 targ_info->user.offset = cts->sync_offset; 646 } 647 if ((update_type & AMD_TRANS_GOAL) != 0) { 648 targ_info->goal.period = cts->sync_period; 649 targ_info->goal.offset = cts->sync_offset; 650 } 651 crit_exit(); 652 pccb->ccb_h.status = CAM_REQ_CMP; 653 xpt_done(pccb); 654 break; 655 } 656 case XPT_CALC_GEOMETRY: 657 { 658 struct ccb_calc_geometry *ccg; 659 u_int32_t size_mb; 660 u_int32_t secs_per_cylinder; 661 int extended; 662 663 ccg = &pccb->ccg; 664 size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size); 665 extended = (amd->eepromBuf[EE_MODE2] & GREATER_1G) != 0; 666 667 if (size_mb > 1024 && extended) { 668 ccg->heads = 255; 669 ccg->secs_per_track = 63; 670 } else { 671 ccg->heads = 64; 672 ccg->secs_per_track = 32; 673 } 674 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 675 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 676 pccb->ccb_h.status = CAM_REQ_CMP; 677 xpt_done(pccb); 678 break; 679 } 680 default: 681 pccb->ccb_h.status = CAM_REQ_INVALID; 682 xpt_done(pccb); 683 break; 684 } 685 } 686 687 static void 688 amd_poll(struct cam_sim * psim) 689 { 690 amd_intr(cam_sim_softc(psim)); 691 } 692 693 static u_int8_t * 694 phystovirt(struct amd_srb * pSRB, u_int32_t xferCnt) 695 { 696 int dataPtr; 697 struct ccb_scsiio *pcsio; 698 u_int8_t i; 699 struct amd_sg * pseg; 700 701 dataPtr = 0; 702 pcsio = &pSRB->pccb->csio; 703 704 dataPtr = (int) pcsio->data_ptr; 705 pseg = pSRB->SGsegment; 706 for (i = 0; i < pSRB->SGIndex; i++) { 707 dataPtr += (int) pseg->SGXLen; 708 pseg++; 709 } 710 dataPtr += (int) xferCnt; 711 return ((u_int8_t *) dataPtr); 712 } 713 714 static void 715 ResetDevParam(struct amd_softc * amd) 716 { 717 u_int target; 718 719 for (target = 0; target <= amd->max_id; target++) { 720 if (amd->AdaptSCSIID != target) { 721 amdsetsync(amd, target, /*clockrate*/0, 722 /*period*/0, /*offset*/0, AMD_TRANS_CUR); 723 } 724 } 725 } 726 727 static void 728 amdcompletematch(struct amd_softc *amd, target_id_t target, lun_id_t lun, 729 u_int tag, struct srb_queue *queue, cam_status status) 730 { 731 struct amd_srb *srb; 732 struct amd_srb *next_srb; 733 734 for (srb = TAILQ_FIRST(queue); srb != NULL; srb = next_srb) { 735 union ccb *ccb; 736 737 next_srb = TAILQ_NEXT(srb, links); 738 if (srb->pccb->ccb_h.target_id != target 739 && target != CAM_TARGET_WILDCARD) 740 continue; 741 742 if (srb->pccb->ccb_h.target_lun != lun 743 && lun != CAM_LUN_WILDCARD) 744 continue; 745 746 if (srb->TagNumber != tag 747 && tag != AMD_TAG_WILDCARD) 748 continue; 749 750 ccb = srb->pccb; 751 TAILQ_REMOVE(queue, srb, links); 752 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links); 753 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0 754 && (status & CAM_DEV_QFRZN) != 0) 755 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 756 ccb->ccb_h.status = status; 757 xpt_done(ccb); 758 } 759 760 } 761 762 static void 763 amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate, 764 u_int period, u_int offset, u_int type) 765 { 766 struct amd_target_info *tinfo; 767 u_int old_period; 768 u_int old_offset; 769 770 tinfo = &amd->tinfo[target]; 771 old_period = tinfo->current.period; 772 old_offset = tinfo->current.offset; 773 if ((type & AMD_TRANS_CUR) != 0 774 && (old_period != period || old_offset != offset)) { 775 struct cam_path *path; 776 777 tinfo->current.period = period; 778 tinfo->current.offset = offset; 779 tinfo->sync_period_reg = clockrate; 780 tinfo->sync_offset_reg = offset; 781 tinfo->CtrlR3 &= ~FAST_SCSI; 782 tinfo->CtrlR4 &= ~EATER_25NS; 783 if (clockrate > 7) 784 tinfo->CtrlR4 |= EATER_25NS; 785 else 786 tinfo->CtrlR3 |= FAST_SCSI; 787 788 if ((type & AMD_TRANS_ACTIVE) == AMD_TRANS_ACTIVE) { 789 amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg); 790 amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg); 791 amd_write8(amd, CNTLREG3, tinfo->CtrlR3); 792 amd_write8(amd, CNTLREG4, tinfo->CtrlR4); 793 } 794 /* If possible, update the XPT's notion of our transfer rate */ 795 if (xpt_create_path(&path, /*periph*/NULL, 796 cam_sim_path(amd->psim), target, 797 CAM_LUN_WILDCARD) == CAM_REQ_CMP) { 798 struct ccb_trans_settings neg; 799 800 xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1); 801 neg.sync_period = period; 802 neg.sync_offset = offset; 803 neg.valid = CCB_TRANS_SYNC_RATE_VALID 804 | CCB_TRANS_SYNC_OFFSET_VALID; 805 xpt_async(AC_TRANSFER_NEG, path, &neg); 806 xpt_free_path(path); 807 } 808 } 809 if ((type & AMD_TRANS_GOAL) != 0) { 810 tinfo->goal.period = period; 811 tinfo->goal.offset = offset; 812 } 813 814 if ((type & AMD_TRANS_USER) != 0) { 815 tinfo->user.period = period; 816 tinfo->user.offset = offset; 817 } 818 } 819 820 static void 821 amdsettags(struct amd_softc *amd, u_int target, int tagenb) 822 { 823 panic("Implement me!\n"); 824 } 825 826 827 #if 0 828 /* 829 ********************************************************************** 830 * Function : amd_reset (struct amd_softc * amd) 831 * Purpose : perform a hard reset on the SCSI bus( and AMD chip). 832 * Inputs : cmd - command which caused the SCSI RESET 833 ********************************************************************** 834 */ 835 static void 836 amd_reset(struct amd_softc * amd) 837 { 838 u_int8_t bval; 839 u_int16_t i; 840 841 842 #ifdef AMD_DEBUG0 843 printf("DC390: RESET"); 844 #endif 845 846 crit_enter(); 847 bval = amd_read8(amd, CNTLREG1); 848 bval |= DIS_INT_ON_SCSI_RST; 849 amd_write8(amd, CNTLREG1, bval); /* disable interrupt */ 850 amd_ResetSCSIBus(amd); 851 852 for (i = 0; i < 500; i++) { 853 DELAY(1000); 854 } 855 856 bval = amd_read8(amd, CNTLREG1); 857 bval &= ~DIS_INT_ON_SCSI_RST; 858 amd_write8(amd, CNTLREG1, bval); /* re-enable interrupt */ 859 860 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD); 861 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 862 863 ResetDevParam(amd); 864 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD, 865 AMD_TAG_WILDCARD, &amd->running_srbs, 866 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET); 867 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD, 868 AMD_TAG_WILDCARD, &amd->waiting_srbs, 869 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET); 870 amd->active_srb = NULL; 871 amd->ACBFlag = 0; 872 crit_exit(); 873 return; 874 } 875 876 void 877 amd_timeout(void *arg1) 878 { 879 struct amd_srb * pSRB; 880 881 pSRB = (struct amd_srb *) arg1; 882 } 883 #endif 884 885 static int 886 amdstart(struct amd_softc *amd, struct amd_srb *pSRB) 887 { 888 union ccb *pccb; 889 struct ccb_scsiio *pcsio; 890 struct amd_target_info *targ_info; 891 u_int identify_msg; 892 u_int command; 893 u_int target; 894 u_int lun; 895 int tagged; 896 897 pccb = pSRB->pccb; 898 pcsio = &pccb->csio; 899 target = pccb->ccb_h.target_id; 900 lun = pccb->ccb_h.target_lun; 901 targ_info = &amd->tinfo[target]; 902 903 amd_clear_msg_state(amd); 904 amd_write8(amd, SCSIDESTIDREG, target); 905 amd_write8(amd, SYNCPERIOREG, targ_info->sync_period_reg); 906 amd_write8(amd, SYNCOFFREG, targ_info->sync_offset_reg); 907 amd_write8(amd, CNTLREG1, targ_info->CtrlR1); 908 amd_write8(amd, CNTLREG3, targ_info->CtrlR3); 909 amd_write8(amd, CNTLREG4, targ_info->CtrlR4); 910 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 911 912 identify_msg = MSG_IDENTIFYFLAG | lun; 913 if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0 914 && (pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0 915 && (pSRB->CmdBlock[0] != REQUEST_SENSE) 916 && (pSRB->SRBFlag & AUTO_REQSENSE) == 0) 917 identify_msg |= MSG_IDENTIFY_DISCFLAG; 918 919 amd_write8(amd, SCSIFIFOREG, identify_msg); 920 tagged = 0; 921 if ((targ_info->disc_tag & AMD_CUR_TAGENB) == 0 922 || (identify_msg & MSG_IDENTIFY_DISCFLAG) == 0) 923 pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID; 924 if (targ_info->current.period != targ_info->goal.period 925 || targ_info->current.offset != targ_info->goal.offset) { 926 command = SEL_W_ATN_STOP; 927 amdconstructsdtr(amd, targ_info->goal.period, 928 targ_info->goal.offset); 929 } else if ((pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 930 command = SEL_W_ATN2; 931 pSRB->SRBState = SRB_START; 932 amd_write8(amd, SCSIFIFOREG, pcsio->tag_action); 933 amd_write8(amd, SCSIFIFOREG, pSRB->TagNumber); 934 tagged++; 935 } else { 936 command = SEL_W_ATN; 937 pSRB->SRBState = SRB_START; 938 } 939 if (command != SEL_W_ATN_STOP) 940 amdsetupcommand(amd, pSRB); 941 942 if (amd_read8(amd, SCSISTATREG) & INTERRUPT) { 943 pSRB->SRBState = SRB_READY; 944 return (1); 945 } else { 946 amd->last_phase = SCSI_ARBITRATING; 947 amd_write8(amd, SCSICMDREG, command); 948 amd->active_srb = pSRB; 949 amd->cur_target = target; 950 amd->cur_lun = lun; 951 return (0); 952 } 953 } 954 955 /* 956 * Catch an interrupt from the adapter. 957 * Process pending device interrupts. 958 */ 959 static void 960 amd_intr(void *arg) 961 { 962 struct amd_softc *amd; 963 struct amd_srb *pSRB; 964 u_int internstat = 0; 965 u_int scsistat; 966 u_int intstat; 967 968 amd = (struct amd_softc *)arg; 969 970 if (amd == NULL) { 971 #ifdef AMD_DEBUG0 972 printf("amd_intr: amd NULL return......"); 973 #endif 974 return; 975 } 976 977 scsistat = amd_read8(amd, SCSISTATREG); 978 if (!(scsistat & INTERRUPT)) { 979 #ifdef AMD_DEBUG0 980 printf("amd_intr: scsistat = NULL ,return......"); 981 #endif 982 return; 983 } 984 #ifdef AMD_DEBUG_SCSI_PHASE 985 printf("scsistat=%2x,", scsistat); 986 #endif 987 988 internstat = amd_read8(amd, INTERNSTATREG); 989 intstat = amd_read8(amd, INTSTATREG); 990 991 #ifdef AMD_DEBUG_SCSI_PHASE 992 printf("intstat=%2x,", intstat); 993 #endif 994 995 if (intstat & DISCONNECTED) { 996 amd_Disconnect(amd); 997 return; 998 } 999 if (intstat & RESELECTED) { 1000 amd_Reselect(amd); 1001 return; 1002 } 1003 if (intstat & INVALID_CMD) { 1004 amd_InvalidCmd(amd); 1005 return; 1006 } 1007 if (intstat & SCSI_RESET_) { 1008 amd_ScsiRstDetect(amd); 1009 return; 1010 } 1011 if (intstat & (SUCCESSFUL_OP + SERVICE_REQUEST)) { 1012 pSRB = amd->active_srb; 1013 /* 1014 * Run our state engine. First perform 1015 * post processing for the last phase we 1016 * were in, followed by any processing 1017 * required to handle the current phase. 1018 */ 1019 scsistat = 1020 amd_SCSI_phase0[amd->last_phase](amd, pSRB, scsistat); 1021 amd->last_phase = scsistat & SCSI_PHASE_MASK; 1022 (void)amd_SCSI_phase1[amd->last_phase](amd, pSRB, scsistat); 1023 } 1024 } 1025 1026 static u_int 1027 amd_DataOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1028 { 1029 struct amd_sg *psgl; 1030 u_int32_t ResidCnt, xferCnt; 1031 1032 if (!(pSRB->SRBState & SRB_XFERPAD)) { 1033 if (scsistat & PARITY_ERR) { 1034 pSRB->SRBStatus |= PARITY_ERROR; 1035 } 1036 if (scsistat & COUNT_2_ZERO) { 1037 while ((amd_read8(amd, DMA_Status)&DMA_XFER_DONE) == 0) 1038 ; 1039 pSRB->TotalXferredLen += pSRB->SGToBeXferLen; 1040 pSRB->SGIndex++; 1041 if (pSRB->SGIndex < pSRB->SGcount) { 1042 pSRB->pSGlist++; 1043 psgl = pSRB->pSGlist; 1044 pSRB->SGPhysAddr = psgl->SGXPtr; 1045 pSRB->SGToBeXferLen = psgl->SGXLen; 1046 } else { 1047 pSRB->SGToBeXferLen = 0; 1048 } 1049 } else { 1050 ResidCnt = amd_read8(amd, CURRENTFIFOREG) & 0x1f; 1051 ResidCnt += amd_read8(amd, CTCREG_LOW) 1052 | (amd_read8(amd, CTCREG_MID) << 8) 1053 | (amd_read8(amd, CURTXTCNTREG) << 16); 1054 1055 xferCnt = pSRB->SGToBeXferLen - ResidCnt; 1056 pSRB->SGPhysAddr += xferCnt; 1057 pSRB->TotalXferredLen += xferCnt; 1058 pSRB->SGToBeXferLen = ResidCnt; 1059 } 1060 } 1061 amd_write8(amd, DMA_Cmd, WRITE_DIRECTION | DMA_IDLE_CMD); 1062 return (scsistat); 1063 } 1064 1065 static u_int 1066 amd_DataInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1067 { 1068 u_int8_t bval; 1069 u_int16_t i, residual; 1070 struct amd_sg *psgl; 1071 u_int32_t ResidCnt, xferCnt; 1072 u_int8_t * ptr; 1073 1074 if (!(pSRB->SRBState & SRB_XFERPAD)) { 1075 if (scsistat & PARITY_ERR) { 1076 pSRB->SRBStatus |= PARITY_ERROR; 1077 } 1078 if (scsistat & COUNT_2_ZERO) { 1079 while (1) { 1080 bval = amd_read8(amd, DMA_Status); 1081 if ((bval & DMA_XFER_DONE) != 0) 1082 break; 1083 } 1084 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD); 1085 1086 pSRB->TotalXferredLen += pSRB->SGToBeXferLen; 1087 pSRB->SGIndex++; 1088 if (pSRB->SGIndex < pSRB->SGcount) { 1089 pSRB->pSGlist++; 1090 psgl = pSRB->pSGlist; 1091 pSRB->SGPhysAddr = psgl->SGXPtr; 1092 pSRB->SGToBeXferLen = psgl->SGXLen; 1093 } else { 1094 pSRB->SGToBeXferLen = 0; 1095 } 1096 } else { /* phase changed */ 1097 residual = 0; 1098 bval = amd_read8(amd, CURRENTFIFOREG); 1099 while (bval & 0x1f) { 1100 if ((bval & 0x1f) == 1) { 1101 for (i = 0; i < 0x100; i++) { 1102 bval = amd_read8(amd, CURRENTFIFOREG); 1103 if (!(bval & 0x1f)) { 1104 goto din_1; 1105 } else if (i == 0x0ff) { 1106 residual = 1; 1107 goto din_1; 1108 } 1109 } 1110 } else { 1111 bval = amd_read8(amd, CURRENTFIFOREG); 1112 } 1113 } 1114 din_1: 1115 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_BLAST_CMD); 1116 for (i = 0; i < 0x8000; i++) { 1117 if ((amd_read8(amd, DMA_Status)&BLAST_COMPLETE)) 1118 break; 1119 } 1120 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD); 1121 1122 ResidCnt = amd_read8(amd, CTCREG_LOW) 1123 | (amd_read8(amd, CTCREG_MID) << 8) 1124 | (amd_read8(amd, CURTXTCNTREG) << 16); 1125 xferCnt = pSRB->SGToBeXferLen - ResidCnt; 1126 pSRB->SGPhysAddr += xferCnt; 1127 pSRB->TotalXferredLen += xferCnt; 1128 pSRB->SGToBeXferLen = ResidCnt; 1129 if (residual) { 1130 /* get residual byte */ 1131 bval = amd_read8(amd, SCSIFIFOREG); 1132 ptr = phystovirt(pSRB, xferCnt); 1133 *ptr = bval; 1134 pSRB->SGPhysAddr++; 1135 pSRB->TotalXferredLen++; 1136 pSRB->SGToBeXferLen--; 1137 } 1138 } 1139 } 1140 return (scsistat); 1141 } 1142 1143 static u_int 1144 amd_StatusPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1145 { 1146 pSRB->TargetStatus = amd_read8(amd, SCSIFIFOREG); 1147 /* get message */ 1148 pSRB->EndMessage = amd_read8(amd, SCSIFIFOREG); 1149 pSRB->SRBState = SRB_COMPLETED; 1150 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD); 1151 return (SCSI_NOP0); 1152 } 1153 1154 static u_int 1155 amd_MsgOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1156 { 1157 if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) { 1158 scsistat = SCSI_NOP0; 1159 } 1160 return (scsistat); 1161 } 1162 1163 static u_int 1164 amd_MsgInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1165 { 1166 int done; 1167 1168 amd->msgin_buf[amd->msgin_index] = amd_read8(amd, SCSIFIFOREG); 1169 1170 done = amdparsemsg(amd); 1171 if (done) 1172 amd->msgin_index = 0; 1173 else 1174 amd->msgin_index++; 1175 return (SCSI_NOP0); 1176 } 1177 1178 static int 1179 amdparsemsg(struct amd_softc *amd) 1180 { 1181 struct amd_target_info *targ_info; 1182 int reject; 1183 int done; 1184 int response; 1185 1186 done = FALSE; 1187 response = FALSE; 1188 reject = FALSE; 1189 1190 targ_info = &amd->tinfo[amd->cur_target]; 1191 1192 /* 1193 * Parse as much of the message as is availible, 1194 * rejecting it if we don't support it. When 1195 * the entire message is availible and has been 1196 * handled, return TRUE indicating that we have 1197 * parsed an entire message. 1198 */ 1199 switch (amd->msgin_buf[0]) { 1200 case MSG_DISCONNECT: 1201 amd->active_srb->SRBState = SRB_DISCONNECT; 1202 amd->disc_count[amd->cur_target][amd->cur_lun]++; 1203 done = TRUE; 1204 break; 1205 case MSG_SIMPLE_Q_TAG: 1206 { 1207 struct amd_srb *disc_srb; 1208 1209 if (amd->msgin_index < 1) 1210 break; 1211 disc_srb = &amd->SRB_array[amd->msgin_buf[1]]; 1212 if (amd->active_srb != NULL 1213 || disc_srb->SRBState != SRB_DISCONNECT 1214 || disc_srb->pccb->ccb_h.target_id != amd->cur_target 1215 || disc_srb->pccb->ccb_h.target_lun != amd->cur_lun) { 1216 printf("amd%d: Unexpected tagged reselection " 1217 "for target %d, Issuing Abort\n", amd->unit, 1218 amd->cur_target); 1219 amd->msgout_buf[0] = MSG_ABORT; 1220 amd->msgout_len = 1; 1221 response = TRUE; 1222 break; 1223 } 1224 amd->active_srb = disc_srb; 1225 amd->disc_count[amd->cur_target][amd->cur_lun]--; 1226 done = TRUE; 1227 break; 1228 } 1229 case MSG_MESSAGE_REJECT: 1230 response = amdhandlemsgreject(amd); 1231 if (response == FALSE) 1232 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD); 1233 /* FALLTHROUGH */ 1234 case MSG_NOOP: 1235 done = TRUE; 1236 break; 1237 case MSG_EXTENDED: 1238 { 1239 u_int clockrate; 1240 u_int period; 1241 u_int offset; 1242 u_int saved_offset; 1243 1244 /* Wait for enough of the message to begin validation */ 1245 if (amd->msgin_index < 1) 1246 break; 1247 if (amd->msgin_buf[1] != MSG_EXT_SDTR_LEN) { 1248 reject = TRUE; 1249 break; 1250 } 1251 1252 /* Wait for opcode */ 1253 if (amd->msgin_index < 2) 1254 break; 1255 1256 if (amd->msgin_buf[2] != MSG_EXT_SDTR) { 1257 reject = TRUE; 1258 break; 1259 } 1260 1261 /* 1262 * Wait until we have both args before validating 1263 * and acting on this message. 1264 * 1265 * Add one to MSG_EXT_SDTR_LEN to account for 1266 * the extended message preamble. 1267 */ 1268 if (amd->msgin_index < (MSG_EXT_SDTR_LEN + 1)) 1269 break; 1270 1271 period = amd->msgin_buf[3]; 1272 saved_offset = offset = amd->msgin_buf[4]; 1273 clockrate = amdfindclockrate(amd, &period); 1274 if (offset > AMD_MAX_SYNC_OFFSET) 1275 offset = AMD_MAX_SYNC_OFFSET; 1276 if (period == 0 || offset == 0) { 1277 offset = 0; 1278 period = 0; 1279 clockrate = 0; 1280 } 1281 amdsetsync(amd, amd->cur_target, clockrate, period, offset, 1282 AMD_TRANS_ACTIVE|AMD_TRANS_GOAL); 1283 1284 /* 1285 * See if we initiated Sync Negotiation 1286 * and didn't have to fall down to async 1287 * transfers. 1288 */ 1289 if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/TRUE)) { 1290 /* We started it */ 1291 if (saved_offset != offset) { 1292 /* Went too low - force async */ 1293 reject = TRUE; 1294 } 1295 } else { 1296 /* 1297 * Send our own SDTR in reply 1298 */ 1299 if (bootverbose) 1300 printf("Sending SDTR!\n"); 1301 amd->msgout_index = 0; 1302 amd->msgout_len = 0; 1303 amdconstructsdtr(amd, period, offset); 1304 amd->msgout_index = 0; 1305 response = TRUE; 1306 } 1307 done = TRUE; 1308 break; 1309 } 1310 case MSG_SAVEDATAPOINTER: 1311 case MSG_RESTOREPOINTERS: 1312 /* XXX Implement!!! */ 1313 done = TRUE; 1314 break; 1315 default: 1316 reject = TRUE; 1317 break; 1318 } 1319 1320 if (reject) { 1321 amd->msgout_index = 0; 1322 amd->msgout_len = 1; 1323 amd->msgout_buf[0] = MSG_MESSAGE_REJECT; 1324 done = TRUE; 1325 response = TRUE; 1326 } 1327 1328 if (response) 1329 amd_write8(amd, SCSICMDREG, SET_ATN_CMD); 1330 1331 if (done && !response) 1332 /* Clear the outgoing message buffer */ 1333 amd->msgout_len = 0; 1334 1335 /* Drop Ack */ 1336 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD); 1337 1338 return (done); 1339 } 1340 1341 static u_int 1342 amdfindclockrate(struct amd_softc *amd, u_int *period) 1343 { 1344 u_int i; 1345 u_int clockrate; 1346 1347 for (i = 0; i < sizeof(tinfo_sync_period); i++) { 1348 u_int8_t *table_entry; 1349 1350 table_entry = &tinfo_sync_period[i]; 1351 if (*period <= *table_entry) { 1352 /* 1353 * When responding to a target that requests 1354 * sync, the requested rate may fall between 1355 * two rates that we can output, but still be 1356 * a rate that we can receive. Because of this, 1357 * we want to respond to the target with 1358 * the same rate that it sent to us even 1359 * if the period we use to send data to it 1360 * is lower. Only lower the response period 1361 * if we must. 1362 */ 1363 if (i == 0) { 1364 *period = *table_entry; 1365 } 1366 break; 1367 } 1368 } 1369 1370 if (i == sizeof(tinfo_sync_period)) { 1371 /* Too slow for us. Use asnyc transfers. */ 1372 *period = 0; 1373 clockrate = 0; 1374 } else 1375 clockrate = i + 4; 1376 1377 return (clockrate); 1378 } 1379 1380 /* 1381 * See if we sent a particular extended message to the target. 1382 * If "full" is true, the target saw the full message. 1383 * If "full" is false, the target saw at least the first 1384 * byte of the message. 1385 */ 1386 static int 1387 amdsentmsg(struct amd_softc *amd, u_int msgtype, int full) 1388 { 1389 int found; 1390 int index; 1391 1392 found = FALSE; 1393 index = 0; 1394 1395 while (index < amd->msgout_len) { 1396 if ((amd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0 1397 || amd->msgout_buf[index] == MSG_MESSAGE_REJECT) 1398 index++; 1399 else if (amd->msgout_buf[index] >= MSG_SIMPLE_Q_TAG 1400 && amd->msgout_buf[index] < MSG_IGN_WIDE_RESIDUE) { 1401 /* Skip tag type and tag id */ 1402 index += 2; 1403 } else if (amd->msgout_buf[index] == MSG_EXTENDED) { 1404 /* Found a candidate */ 1405 if (amd->msgout_buf[index+2] == msgtype) { 1406 u_int end_index; 1407 1408 end_index = index + 1 1409 + amd->msgout_buf[index + 1]; 1410 if (full) { 1411 if (amd->msgout_index > end_index) 1412 found = TRUE; 1413 } else if (amd->msgout_index > index) 1414 found = TRUE; 1415 } 1416 break; 1417 } else { 1418 panic("amdsentmsg: Inconsistent msg buffer"); 1419 } 1420 } 1421 return (found); 1422 } 1423 1424 static void 1425 amdconstructsdtr(struct amd_softc *amd, u_int period, u_int offset) 1426 { 1427 amd->msgout_buf[amd->msgout_index++] = MSG_EXTENDED; 1428 amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR_LEN; 1429 amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR; 1430 amd->msgout_buf[amd->msgout_index++] = period; 1431 amd->msgout_buf[amd->msgout_index++] = offset; 1432 amd->msgout_len += 5; 1433 } 1434 1435 static int 1436 amdhandlemsgreject(struct amd_softc *amd) 1437 { 1438 /* 1439 * If we had an outstanding SDTR for this 1440 * target, this is a signal that the target 1441 * is refusing negotiation. Also watch out 1442 * for rejected tag messages. 1443 */ 1444 struct amd_srb *srb; 1445 struct amd_target_info *targ_info; 1446 int response = FALSE; 1447 1448 srb = amd->active_srb; 1449 targ_info = &amd->tinfo[amd->cur_target]; 1450 if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/FALSE)) { 1451 /* note asynch xfers and clear flag */ 1452 amdsetsync(amd, amd->cur_target, /*clockrate*/0, 1453 /*period*/0, /*offset*/0, 1454 AMD_TRANS_ACTIVE|AMD_TRANS_GOAL); 1455 printf("amd%d:%d: refuses synchronous negotiation. " 1456 "Using asynchronous transfers\n", 1457 amd->unit, amd->cur_target); 1458 } else if ((srb != NULL) 1459 && (srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 1460 struct ccb_trans_settings neg; 1461 1462 printf("amd%d:%d: refuses tagged commands. Performing " 1463 "non-tagged I/O\n", amd->unit, amd->cur_target); 1464 1465 amdsettags(amd, amd->cur_target, FALSE); 1466 neg.flags = 0; 1467 neg.valid = CCB_TRANS_TQ_VALID; 1468 xpt_setup_ccb(&neg.ccb_h, srb->pccb->ccb_h.path, /*priority*/1); 1469 xpt_async(AC_TRANSFER_NEG, srb->pccb->ccb_h.path, &neg); 1470 1471 /* 1472 * Resend the identify for this CCB as the target 1473 * may believe that the selection is invalid otherwise. 1474 */ 1475 if (amd->msgout_len != 0) 1476 bcopy(&amd->msgout_buf[0], &amd->msgout_buf[1], 1477 amd->msgout_len); 1478 amd->msgout_buf[0] = MSG_IDENTIFYFLAG 1479 | srb->pccb->ccb_h.target_lun; 1480 amd->msgout_len++; 1481 if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0 1482 && (srb->pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0) 1483 amd->msgout_buf[0] |= MSG_IDENTIFY_DISCFLAG; 1484 1485 srb->pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID; 1486 1487 /* 1488 * Requeue all tagged commands for this target 1489 * currently in our posession so they can be 1490 * converted to untagged commands. 1491 */ 1492 amdcompletematch(amd, amd->cur_target, amd->cur_lun, 1493 AMD_TAG_WILDCARD, &amd->waiting_srbs, 1494 CAM_DEV_QFRZN|CAM_REQUEUE_REQ); 1495 } else { 1496 /* 1497 * Otherwise, we ignore it. 1498 */ 1499 printf("amd%d:%d: Message reject received -- ignored\n", 1500 amd->unit, amd->cur_target); 1501 } 1502 return (response); 1503 } 1504 1505 #if 0 1506 if (!(pSRB->SRBState & SRB_MSGIN_MULTI)) { 1507 if (bval == MSG_DISCONNECT) { 1508 pSRB->SRBState = SRB_DISCONNECT; 1509 } else if (bval == MSG_SAVEDATAPOINTER) { 1510 goto min6; 1511 } else if ((bval == MSG_EXTENDED) 1512 || ((bval >= MSG_SIMPLE_Q_TAG) 1513 && (bval <= MSG_ORDERED_Q_TAG))) { 1514 pSRB->SRBState |= SRB_MSGIN_MULTI; 1515 pSRB->MsgInBuf[0] = bval; 1516 pSRB->MsgCnt = 1; 1517 pSRB->pMsgPtr = &pSRB->MsgInBuf[1]; 1518 } else if (bval == MSG_MESSAGE_REJECT) { 1519 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD); 1520 1521 if (pSRB->SRBState & DO_SYNC_NEGO) { 1522 goto set_async; 1523 } 1524 } else if (bval == MSG_RESTOREPOINTERS) { 1525 goto min6; 1526 } else { 1527 goto min6; 1528 } 1529 } else { /* minx: */ 1530 *pSRB->pMsgPtr = bval; 1531 pSRB->MsgCnt++; 1532 pSRB->pMsgPtr++; 1533 if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_Q_TAG) 1534 && (pSRB->MsgInBuf[0] <= MSG_ORDERED_Q_TAG)) { 1535 if (pSRB->MsgCnt == 2) { 1536 pSRB->SRBState = 0; 1537 pSRB = &amd->SRB_array[pSRB->MsgInBuf[1]]; 1538 if (pSRB->SRBState & SRB_DISCONNECT) == 0) { 1539 pSRB = amd->pTmpSRB; 1540 pSRB->SRBState = SRB_UNEXPECT_RESEL; 1541 pDCB->pActiveSRB = pSRB; 1542 pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; 1543 EnableMsgOut2(amd, pSRB); 1544 } else { 1545 if (pDCB->DCBFlag & ABORT_DEV_) { 1546 pSRB->SRBState = SRB_ABORT_SENT; 1547 EnableMsgOut1(amd, pSRB); 1548 } 1549 pDCB->pActiveSRB = pSRB; 1550 pSRB->SRBState = SRB_DATA_XFER; 1551 } 1552 } 1553 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) 1554 && (pSRB->MsgCnt == 5)) { 1555 pSRB->SRBState &= ~(SRB_MSGIN_MULTI + DO_SYNC_NEGO); 1556 if ((pSRB->MsgInBuf[1] != 3) 1557 || (pSRB->MsgInBuf[2] != 1)) { /* reject_msg: */ 1558 pSRB->MsgCnt = 1; 1559 pSRB->MsgInBuf[0] = MSG_MESSAGE_REJECT; 1560 amd_write8(amd, SCSICMDREG, SET_ATN_CMD); 1561 } else if (!(pSRB->MsgInBuf[3]) 1562 || !(pSRB->MsgInBuf[4])) { 1563 set_async: /* set async */ 1564 1565 pDCB = pSRB->pSRBDCB; 1566 /* disable sync & sync nego */ 1567 pDCB->SyncMode &= ~(SYNC_ENABLE|SYNC_NEGO_DONE); 1568 pDCB->SyncPeriod = 0; 1569 pDCB->SyncOffset = 0; 1570 1571 pDCB->tinfo.goal.period = 0; 1572 pDCB->tinfo.goal.offset = 0; 1573 1574 pDCB->tinfo.current.period = 0; 1575 pDCB->tinfo.current.offset = 0; 1576 pDCB->tinfo.current.width = 1577 MSG_EXT_WDTR_BUS_8_BIT; 1578 1579 pDCB->CtrlR3 = FAST_CLK; /* non_fast */ 1580 pDCB->CtrlR4 &= 0x3f; 1581 pDCB->CtrlR4 |= EATER_25NS; 1582 goto re_prog; 1583 } else {/* set sync */ 1584 1585 pDCB = pSRB->pSRBDCB; 1586 /* enable sync & sync nego */ 1587 pDCB->SyncMode |= SYNC_ENABLE|SYNC_NEGO_DONE; 1588 1589 /* set sync offset */ 1590 pDCB->SyncOffset &= 0x0f0; 1591 pDCB->SyncOffset |= pSRB->MsgInBuf[4]; 1592 1593 /* set sync period */ 1594 pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3]; 1595 1596 wval = (u_int16_t) pSRB->MsgInBuf[3]; 1597 wval = wval << 2; 1598 wval--; 1599 wval1 = wval / 25; 1600 if ((wval1 * 25) != wval) { 1601 wval1++; 1602 } 1603 bval = FAST_CLK|FAST_SCSI; 1604 pDCB->CtrlR4 &= 0x3f; 1605 if (wval1 >= 8) { 1606 /* Fast SCSI */ 1607 wval1--; 1608 bval = FAST_CLK; 1609 pDCB->CtrlR4 |= EATER_25NS; 1610 } 1611 pDCB->CtrlR3 = bval; 1612 pDCB->SyncPeriod = (u_int8_t) wval1; 1613 1614 pDCB->tinfo.goal.period = 1615 tinfo_sync_period[pDCB->SyncPeriod - 4]; 1616 pDCB->tinfo.goal.offset = pDCB->SyncOffset; 1617 pDCB->tinfo.current.period = 1618 tinfo_sync_period[pDCB->SyncPeriod - 4];; 1619 pDCB->tinfo.current.offset = pDCB->SyncOffset; 1620 1621 /* 1622 * program SCSI control register 1623 */ 1624 re_prog: 1625 amd_write8(amd, SYNCPERIOREG, pDCB->SyncPeriod); 1626 amd_write8(amd, SYNCOFFREG, pDCB->SyncOffset); 1627 amd_write8(amd, CNTLREG3, pDCB->CtrlR3); 1628 amd_write8(amd, CNTLREG4, pDCB->CtrlR4); 1629 } 1630 } 1631 } 1632 min6: 1633 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD); 1634 return (SCSI_NOP0); 1635 } 1636 #endif 1637 1638 static u_int 1639 amd_DataOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1640 { 1641 DataIO_Comm(amd, pSRB, WRITE_DIRECTION); 1642 return (scsistat); 1643 } 1644 1645 static u_int 1646 amd_DataInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1647 { 1648 DataIO_Comm(amd, pSRB, READ_DIRECTION); 1649 return (scsistat); 1650 } 1651 1652 static void 1653 DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int ioDir) 1654 { 1655 struct amd_sg * psgl; 1656 u_int32_t lval; 1657 1658 if (pSRB->SGIndex < pSRB->SGcount) { 1659 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir);/* |EN_DMA_INT */ 1660 1661 if (!pSRB->SGToBeXferLen) { 1662 psgl = pSRB->pSGlist; 1663 pSRB->SGPhysAddr = psgl->SGXPtr; 1664 pSRB->SGToBeXferLen = psgl->SGXLen; 1665 } 1666 lval = pSRB->SGToBeXferLen; 1667 amd_write8(amd, CTCREG_LOW, lval); 1668 amd_write8(amd, CTCREG_MID, lval >> 8); 1669 amd_write8(amd, CURTXTCNTREG, lval >> 16); 1670 1671 amd_write32(amd, DMA_XferCnt, pSRB->SGToBeXferLen); 1672 1673 amd_write32(amd, DMA_XferAddr, pSRB->SGPhysAddr); 1674 1675 pSRB->SRBState = SRB_DATA_XFER; 1676 1677 amd_write8(amd, SCSICMDREG, DMA_COMMAND|INFO_XFER_CMD); 1678 1679 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir); /* |EN_DMA_INT */ 1680 1681 amd_write8(amd, DMA_Cmd, DMA_START_CMD|ioDir);/* |EN_DMA_INT */ 1682 } else { /* xfer pad */ 1683 if (pSRB->SGcount) { 1684 pSRB->AdaptStatus = H_OVER_UNDER_RUN; 1685 pSRB->SRBStatus |= OVER_RUN; 1686 } 1687 amd_write8(amd, CTCREG_LOW, 0); 1688 amd_write8(amd, CTCREG_MID, 0); 1689 amd_write8(amd, CURTXTCNTREG, 0); 1690 1691 pSRB->SRBState |= SRB_XFERPAD; 1692 amd_write8(amd, SCSICMDREG, DMA_COMMAND|XFER_PAD_BYTE); 1693 } 1694 } 1695 1696 static u_int 1697 amd_CommandPhase1(struct amd_softc *amd, struct amd_srb *srb, u_int scsistat) 1698 { 1699 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD); 1700 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 1701 1702 amdsetupcommand(amd, srb); 1703 1704 srb->SRBState = SRB_COMMAND; 1705 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD); 1706 return (scsistat); 1707 } 1708 1709 static u_int 1710 amd_StatusPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1711 { 1712 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 1713 pSRB->SRBState = SRB_STATUS; 1714 amd_write8(amd, SCSICMDREG, INITIATOR_CMD_CMPLTE); 1715 return (scsistat); 1716 } 1717 1718 static u_int 1719 amd_MsgOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1720 { 1721 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 1722 1723 if (amd->msgout_len == 0) { 1724 amd->msgout_buf[0] = MSG_NOOP; 1725 amd->msgout_len = 1; 1726 } 1727 amd_write8_multi(amd, SCSIFIFOREG, amd->msgout_buf, amd->msgout_len); 1728 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD); 1729 return (scsistat); 1730 } 1731 1732 static u_int 1733 amd_MsgInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1734 { 1735 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 1736 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD); 1737 return (scsistat); 1738 } 1739 1740 static u_int 1741 amd_NopPhase(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat) 1742 { 1743 return (scsistat); 1744 } 1745 1746 static void 1747 amd_Disconnect(struct amd_softc * amd) 1748 { 1749 struct amd_srb *srb; 1750 int target; 1751 int lun; 1752 1753 srb = amd->active_srb; 1754 amd->active_srb = NULL; 1755 amd->last_phase = SCSI_BUS_FREE; 1756 amd_write8(amd, SCSICMDREG, EN_SEL_RESEL); 1757 target = amd->cur_target; 1758 lun = amd->cur_lun; 1759 1760 if (srb == NULL) { 1761 /* Invalid reselection */ 1762 amdrunwaiting(amd); 1763 } else if (srb->SRBState & SRB_ABORT_SENT) { 1764 /* Clean up and done this srb */ 1765 #if 0 1766 while (( = TAILQ_FIRST(&amd->running_srbs)) != NULL) { 1767 /* XXX What about "done'ing" these srbs??? */ 1768 if (pSRB->pSRBDCB == pDCB) { 1769 TAILQ_REMOVE(&amd->running_srbs, pSRB, links); 1770 TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links); 1771 } 1772 } 1773 amdrunwaiting(amd); 1774 #endif 1775 } else { 1776 if ((srb->SRBState & (SRB_START | SRB_MSGOUT)) 1777 || !(srb->SRBState & (SRB_DISCONNECT | SRB_COMPLETED))) { 1778 srb->TargetStatus = AMD_SCSI_STAT_SEL_TIMEOUT; 1779 goto disc1; 1780 } else if (srb->SRBState & SRB_DISCONNECT) { 1781 if (!(srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID)) 1782 amd->untagged_srbs[target][lun] = srb; 1783 amdrunwaiting(amd); 1784 } else if (srb->SRBState & SRB_COMPLETED) { 1785 disc1: 1786 srb->SRBState = SRB_FREE; 1787 SRBdone(amd, srb); 1788 } 1789 } 1790 return; 1791 } 1792 1793 static void 1794 amd_Reselect(struct amd_softc *amd) 1795 { 1796 struct amd_target_info *tinfo; 1797 u_int16_t disc_count; 1798 1799 amd_clear_msg_state(amd); 1800 if (amd->active_srb != NULL) { 1801 /* Requeue the SRB for our attempted Selection */ 1802 TAILQ_REMOVE(&amd->running_srbs, amd->active_srb, links); 1803 TAILQ_INSERT_HEAD(&amd->waiting_srbs, amd->active_srb, links); 1804 amd->active_srb = NULL; 1805 } 1806 /* get ID */ 1807 amd->cur_target = amd_read8(amd, SCSIFIFOREG); 1808 amd->cur_target ^= amd->HostID_Bit; 1809 amd->cur_target = ffs(amd->cur_target) - 1; 1810 amd->cur_lun = amd_read8(amd, SCSIFIFOREG) & 7; 1811 tinfo = &amd->tinfo[amd->cur_target]; 1812 amd->active_srb = amd->untagged_srbs[amd->cur_target][amd->cur_lun]; 1813 disc_count = amd->disc_count[amd->cur_target][amd->cur_lun]; 1814 if (disc_count == 0) { 1815 printf("amd%d: Unexpected reselection for target %d, " 1816 "Issuing Abort\n", amd->unit, amd->cur_target); 1817 amd->msgout_buf[0] = MSG_ABORT; 1818 amd->msgout_len = 1; 1819 amd_write8(amd, SCSICMDREG, SET_ATN_CMD); 1820 } 1821 if (amd->active_srb != NULL) { 1822 amd->disc_count[amd->cur_target][amd->cur_lun]--; 1823 amd->untagged_srbs[amd->cur_target][amd->cur_lun] = NULL; 1824 } 1825 1826 amd_write8(amd, SCSIDESTIDREG, amd->cur_target); 1827 amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg); 1828 amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg); 1829 amd_write8(amd, CNTLREG1, tinfo->CtrlR1); 1830 amd_write8(amd, CNTLREG3, tinfo->CtrlR3); 1831 amd_write8(amd, CNTLREG4, tinfo->CtrlR4); 1832 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);/* drop /ACK */ 1833 amd->last_phase = SCSI_NOP0; 1834 } 1835 1836 static void 1837 SRBdone(struct amd_softc *amd, struct amd_srb *pSRB) 1838 { 1839 u_int8_t bval, i, status; 1840 union ccb *pccb; 1841 struct ccb_scsiio *pcsio; 1842 struct amd_sg *ptr2; 1843 u_int32_t swlval; 1844 u_int target_id, target_lun; 1845 1846 pccb = pSRB->pccb; 1847 pcsio = &pccb->csio; 1848 target_id = pSRB->pccb->ccb_h.target_id; 1849 target_lun = pSRB->pccb->ccb_h.target_lun; 1850 1851 CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, 1852 ("SRBdone - TagNumber %d\n", pSRB->TagNumber)); 1853 1854 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1855 bus_dmasync_op_t op; 1856 1857 if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1858 op = BUS_DMASYNC_POSTREAD; 1859 else 1860 op = BUS_DMASYNC_POSTWRITE; 1861 bus_dmamap_sync(amd->buffer_dmat, pSRB->dmamap, op); 1862 bus_dmamap_unload(amd->buffer_dmat, pSRB->dmamap); 1863 } 1864 1865 status = pSRB->TargetStatus; 1866 pccb->ccb_h.status = CAM_REQ_CMP; 1867 pccb->ccb_h.status = CAM_REQ_CMP; 1868 if (pSRB->SRBFlag & AUTO_REQSENSE) { 1869 pSRB->SRBFlag &= ~AUTO_REQSENSE; 1870 pSRB->AdaptStatus = 0; 1871 pSRB->TargetStatus = SCSI_STATUS_CHECK_COND; 1872 1873 if (status == SCSI_STATUS_CHECK_COND) { 1874 pccb->ccb_h.status = CAM_SEL_TIMEOUT; 1875 goto ckc_e; 1876 } 1877 *((u_int32_t *)&(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; 1878 1879 pcsio->sense_resid = pcsio->sense_len 1880 - pSRB->TotalXferredLen; 1881 pSRB->TotalXferredLen = pSRB->Segment1[1]; 1882 if (pSRB->TotalXferredLen) { 1883 /* ???? */ 1884 pcsio->resid = pcsio->dxfer_len 1885 - pSRB->TotalXferredLen; 1886 /* The resid field contains valid data */ 1887 /* Flush resid bytes on complete */ 1888 } else { 1889 pcsio->scsi_status = SCSI_STATUS_CHECK_COND; 1890 } 1891 pccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR; 1892 goto ckc_e; 1893 } 1894 if (status) { 1895 if (status == SCSI_STATUS_CHECK_COND) { 1896 1897 if ((pSRB->SGIndex < pSRB->SGcount) 1898 && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) { 1899 bval = pSRB->SGcount; 1900 swlval = pSRB->SGToBeXferLen; 1901 ptr2 = pSRB->pSGlist; 1902 ptr2++; 1903 for (i = pSRB->SGIndex + 1; i < bval; i++) { 1904 swlval += ptr2->SGXLen; 1905 ptr2++; 1906 } 1907 /* ??????? */ 1908 pcsio->resid = (u_int32_t) swlval; 1909 1910 #ifdef AMD_DEBUG0 1911 printf("XferredLen=%8x,NotYetXferLen=%8x,", 1912 pSRB->TotalXferredLen, swlval); 1913 #endif 1914 } 1915 if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) { 1916 #ifdef AMD_DEBUG0 1917 printf("RequestSense..................\n"); 1918 #endif 1919 RequestSense(amd, pSRB); 1920 return; 1921 } 1922 pcsio->scsi_status = SCSI_STATUS_CHECK_COND; 1923 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 1924 goto ckc_e; 1925 } else if (status == SCSI_STATUS_QUEUE_FULL) { 1926 pSRB->AdaptStatus = 0; 1927 pSRB->TargetStatus = 0; 1928 pcsio->scsi_status = SCSI_STATUS_QUEUE_FULL; 1929 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 1930 goto ckc_e; 1931 } else if (status == AMD_SCSI_STAT_SEL_TIMEOUT) { 1932 pSRB->AdaptStatus = H_SEL_TIMEOUT; 1933 pSRB->TargetStatus = 0; 1934 1935 pcsio->scsi_status = AMD_SCSI_STAT_SEL_TIMEOUT; 1936 pccb->ccb_h.status = CAM_SEL_TIMEOUT; 1937 } else if (status == SCSI_STATUS_BUSY) { 1938 #ifdef AMD_DEBUG0 1939 printf("DC390: target busy at %s %d\n", 1940 __FILE__, __LINE__); 1941 #endif 1942 pcsio->scsi_status = SCSI_STATUS_BUSY; 1943 pccb->ccb_h.status = CAM_SCSI_BUSY; 1944 } else if (status == SCSI_STATUS_RESERV_CONFLICT) { 1945 #ifdef AMD_DEBUG0 1946 printf("DC390: target reserved at %s %d\n", 1947 __FILE__, __LINE__); 1948 #endif 1949 pcsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; 1950 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /* XXX */ 1951 } else { 1952 pSRB->AdaptStatus = 0; 1953 #ifdef AMD_DEBUG0 1954 printf("DC390: driver stuffup at %s %d\n", 1955 __FILE__, __LINE__); 1956 #endif 1957 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 1958 } 1959 } else { 1960 status = pSRB->AdaptStatus; 1961 if (status & H_OVER_UNDER_RUN) { 1962 pSRB->TargetStatus = 0; 1963 1964 pccb->ccb_h.status = CAM_DATA_RUN_ERR; 1965 } else if (pSRB->SRBStatus & PARITY_ERROR) { 1966 #ifdef AMD_DEBUG0 1967 printf("DC390: driver stuffup %s %d\n", 1968 __FILE__, __LINE__); 1969 #endif 1970 /* Driver failed to perform operation */ 1971 pccb->ccb_h.status = CAM_UNCOR_PARITY; 1972 } else { /* No error */ 1973 pSRB->AdaptStatus = 0; 1974 pSRB->TargetStatus = 0; 1975 pcsio->resid = 0; 1976 /* there is no error, (sense is invalid) */ 1977 } 1978 } 1979 ckc_e: 1980 crit_enter(); 1981 if ((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1982 /* CAM request not yet complete =>device_Q frozen */ 1983 xpt_freeze_devq(pccb->ccb_h.path, 1); 1984 pccb->ccb_h.status |= CAM_DEV_QFRZN; 1985 } 1986 TAILQ_REMOVE(&amd->running_srbs, pSRB, links); 1987 TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links); 1988 amdrunwaiting(amd); 1989 crit_exit(); 1990 xpt_done(pccb); 1991 1992 } 1993 1994 static void 1995 amd_ResetSCSIBus(struct amd_softc * amd) 1996 { 1997 crit_enter(); 1998 amd->ACBFlag |= RESET_DEV; 1999 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD); 2000 amd_write8(amd, SCSICMDREG, RST_SCSI_BUS_CMD); 2001 crit_exit(); 2002 return; 2003 } 2004 2005 static void 2006 amd_ScsiRstDetect(struct amd_softc * amd) 2007 { 2008 u_int32_t wlval; 2009 2010 #ifdef AMD_DEBUG0 2011 printf("amd_ScsiRstDetect \n"); 2012 #endif 2013 2014 wlval = 1000; 2015 while (--wlval) { /* delay 1 sec */ 2016 DELAY(1000); 2017 } 2018 crit_enter(); 2019 2020 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD); 2021 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 2022 2023 if (amd->ACBFlag & RESET_DEV) { 2024 amd->ACBFlag |= RESET_DONE; 2025 } else { 2026 amd->ACBFlag |= RESET_DETECT; 2027 ResetDevParam(amd); 2028 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD, 2029 AMD_TAG_WILDCARD, &amd->running_srbs, 2030 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET); 2031 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD, 2032 AMD_TAG_WILDCARD, &amd->waiting_srbs, 2033 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET); 2034 amd->active_srb = NULL; 2035 amd->ACBFlag = 0; 2036 amdrunwaiting(amd); 2037 } 2038 crit_exit(); 2039 return; 2040 } 2041 2042 static void 2043 RequestSense(struct amd_softc *amd, struct amd_srb *pSRB) 2044 { 2045 union ccb *pccb; 2046 struct ccb_scsiio *pcsio; 2047 2048 pccb = pSRB->pccb; 2049 pcsio = &pccb->csio; 2050 2051 pSRB->SRBFlag |= AUTO_REQSENSE; 2052 pSRB->Segment0[0] = *((u_int32_t *) & (pSRB->CmdBlock[0])); 2053 pSRB->Segment0[1] = *((u_int32_t *) & (pSRB->CmdBlock[4])); 2054 pSRB->Segment1[0] = (pSRB->ScsiCmdLen << 8) + pSRB->SGcount; 2055 pSRB->Segment1[1] = pSRB->TotalXferredLen; 2056 2057 pSRB->AdaptStatus = 0; 2058 pSRB->TargetStatus = 0; 2059 2060 pSRB->Segmentx.SGXPtr = (u_int32_t) vtophys(&pcsio->sense_data); 2061 pSRB->Segmentx.SGXLen = (u_int32_t) pcsio->sense_len; 2062 2063 pSRB->pSGlist = &pSRB->Segmentx; 2064 pSRB->SGcount = 1; 2065 pSRB->SGIndex = 0; 2066 2067 *((u_int32_t *) & (pSRB->CmdBlock[0])) = 0x00000003; 2068 pSRB->CmdBlock[1] = pSRB->pccb->ccb_h.target_lun << 5; 2069 *((u_int16_t *) & (pSRB->CmdBlock[4])) = pcsio->sense_len; 2070 pSRB->ScsiCmdLen = 6; 2071 2072 pSRB->TotalXferredLen = 0; 2073 pSRB->SGToBeXferLen = 0; 2074 if (amdstart(amd, pSRB) != 0) { 2075 TAILQ_REMOVE(&amd->running_srbs, pSRB, links); 2076 TAILQ_INSERT_HEAD(&amd->waiting_srbs, pSRB, links); 2077 } 2078 } 2079 2080 static void 2081 amd_InvalidCmd(struct amd_softc * amd) 2082 { 2083 struct amd_srb *srb; 2084 2085 srb = amd->active_srb; 2086 if (srb->SRBState & (SRB_START|SRB_MSGOUT)) 2087 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD); 2088 } 2089 2090 void 2091 amd_linkSRB(struct amd_softc *amd) 2092 { 2093 u_int16_t count, i; 2094 struct amd_srb *psrb; 2095 int error; 2096 2097 count = amd->SRBCount; 2098 2099 for (i = 0; i < count; i++) { 2100 psrb = (struct amd_srb *)&amd->SRB_array[i]; 2101 psrb->TagNumber = i; 2102 2103 /* 2104 * Create the dmamap. This is no longer optional! 2105 */ 2106 error = bus_dmamap_create(amd->buffer_dmat, 0, &psrb->dmamap); 2107 if (error) { 2108 device_printf(amd->dev, "Error %d creating buffer " 2109 "dmamap!\n", error); 2110 break; 2111 } 2112 TAILQ_INSERT_TAIL(&amd->free_srbs, psrb, links); 2113 } 2114 } 2115 2116 void 2117 amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval) 2118 { 2119 if (mode == ENABLE_CE) { 2120 *regval = 0xc0; 2121 } else { 2122 *regval = 0x80; 2123 } 2124 pci_write_config(amd->dev, *regval, 0, /*bytes*/1); 2125 if (mode == DISABLE_CE) { 2126 pci_write_config(amd->dev, *regval, 0, /*bytes*/1); 2127 } 2128 DELAY(160); 2129 } 2130 2131 void 2132 amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry) 2133 { 2134 u_int bval; 2135 2136 bval = 0; 2137 if (Carry) { 2138 bval = 0x40; 2139 *regval = 0x80; 2140 pci_write_config(amd->dev, *regval, bval, /*bytes*/1); 2141 } 2142 DELAY(160); 2143 bval |= 0x80; 2144 pci_write_config(amd->dev, *regval, bval, /*bytes*/1); 2145 DELAY(160); 2146 pci_write_config(amd->dev, *regval, 0, /*bytes*/1); 2147 DELAY(160); 2148 } 2149 2150 static int 2151 amd_EEpromInDO(struct amd_softc *amd) 2152 { 2153 pci_write_config(amd->dev, 0x80, 0x80, /*bytes*/1); 2154 DELAY(160); 2155 pci_write_config(amd->dev, 0x80, 0x40, /*bytes*/1); 2156 DELAY(160); 2157 if (pci_read_config(amd->dev, 0, /*bytes*/1) == 0x22) 2158 return (1); 2159 return (0); 2160 } 2161 2162 static u_int16_t 2163 EEpromGetData1(struct amd_softc *amd) 2164 { 2165 u_int i; 2166 u_int carryFlag; 2167 u_int16_t wval; 2168 2169 wval = 0; 2170 for (i = 0; i < 16; i++) { 2171 wval <<= 1; 2172 carryFlag = amd_EEpromInDO(amd); 2173 wval |= carryFlag; 2174 } 2175 return (wval); 2176 } 2177 2178 static void 2179 amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd) 2180 { 2181 u_int i, j; 2182 int carryFlag; 2183 2184 carryFlag = 1; 2185 j = 0x80; 2186 for (i = 0; i < 9; i++) { 2187 amd_EEpromOutDI(amd, regval, carryFlag); 2188 carryFlag = (EEpromCmd & j) ? 1 : 0; 2189 j >>= 1; 2190 } 2191 } 2192 2193 static void 2194 amd_ReadEEprom(struct amd_softc *amd) 2195 { 2196 int regval; 2197 u_int i; 2198 u_int16_t *ptr; 2199 u_int8_t cmd; 2200 2201 ptr = (u_int16_t *)&amd->eepromBuf[0]; 2202 cmd = EEPROM_READ; 2203 for (i = 0; i < 0x40; i++) { 2204 amd_EnDisableCE(amd, ENABLE_CE, ®val); 2205 amd_Prepare(amd, ®val, cmd); 2206 *ptr = EEpromGetData1(amd); 2207 ptr++; 2208 cmd++; 2209 amd_EnDisableCE(amd, DISABLE_CE, ®val); 2210 } 2211 } 2212 2213 static void 2214 amd_load_defaults(struct amd_softc *amd) 2215 { 2216 int target; 2217 2218 bzero(&amd->eepromBuf, sizeof amd->eepromBuf); 2219 for (target = 0; target < MAX_SCSI_ID; target++) 2220 amd->eepromBuf[target << 2] = 2221 (TAG_QUEUING|EN_DISCONNECT|SYNC_NEGO|PARITY_CHK); 2222 amd->eepromBuf[EE_ADAPT_SCSI_ID] = 7; 2223 amd->eepromBuf[EE_MODE2] = ACTIVE_NEGATION|LUN_CHECK|GREATER_1G; 2224 amd->eepromBuf[EE_TAG_CMD_NUM] = 4; 2225 } 2226 2227 static void 2228 amd_load_eeprom_or_defaults(struct amd_softc *amd) 2229 { 2230 u_int16_t wval, *ptr; 2231 u_int8_t i; 2232 2233 amd_ReadEEprom(amd); 2234 wval = 0; 2235 ptr = (u_int16_t *) & amd->eepromBuf[0]; 2236 for (i = 0; i < EE_DATA_SIZE; i += 2, ptr++) 2237 wval += *ptr; 2238 2239 if (wval != EE_CHECKSUM) { 2240 if (bootverbose) 2241 printf("amd%d: SEEPROM data unavailable. " 2242 "Using default device parameters.\n", 2243 amd->unit); 2244 amd_load_defaults(amd); 2245 } 2246 } 2247 2248 /* 2249 ********************************************************************** 2250 * Function : static int amd_init (struct Scsi_Host *host) 2251 * Purpose : initialize the internal structures for a given SCSI host 2252 * Inputs : host - pointer to this host adapter's structure/ 2253 ********************************************************************** 2254 */ 2255 static int 2256 amd_init(device_t dev) 2257 { 2258 struct amd_softc *amd = device_get_softc(dev); 2259 struct resource *iores; 2260 int i, rid; 2261 u_int bval; 2262 2263 rid = PCI_BASE_ADDR0; 2264 iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 2265 RF_ACTIVE); 2266 if (iores == NULL) { 2267 if (bootverbose) 2268 printf("amd_init: bus_alloc_resource failure!\n"); 2269 return ENXIO; 2270 } 2271 amd->tag = rman_get_bustag(iores); 2272 amd->bsh = rman_get_bushandle(iores); 2273 2274 /* DMA tag for mapping buffers into device visible space. */ 2275 if (bus_dma_tag_create(/*parent_dmat*/NULL, /*alignment*/1, 2276 /*boundary*/0, 2277 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 2278 /*highaddr*/BUS_SPACE_MAXADDR, 2279 /*filter*/NULL, /*filterarg*/NULL, 2280 /*maxsize*/MAXBSIZE, /*nsegments*/AMD_NSEG, 2281 /*maxsegsz*/AMD_MAXTRANSFER_SIZE, 2282 /*flags*/BUS_DMA_ALLOCNOW, 2283 &amd->buffer_dmat) != 0) { 2284 if (bootverbose) 2285 printf("amd_init: bus_dma_tag_create failure!\n"); 2286 return ENXIO; 2287 } 2288 TAILQ_INIT(&amd->free_srbs); 2289 TAILQ_INIT(&amd->running_srbs); 2290 TAILQ_INIT(&amd->waiting_srbs); 2291 amd->last_phase = SCSI_BUS_FREE; 2292 amd->dev = dev; 2293 amd->unit = device_get_unit(dev); 2294 amd->SRBCount = MAX_SRB_CNT; 2295 amd->status = 0; 2296 amd_load_eeprom_or_defaults(amd); 2297 amd->max_id = 7; 2298 if (amd->eepromBuf[EE_MODE2] & LUN_CHECK) { 2299 amd->max_lun = 7; 2300 } else { 2301 amd->max_lun = 0; 2302 } 2303 amd->AdaptSCSIID = amd->eepromBuf[EE_ADAPT_SCSI_ID]; 2304 amd->HostID_Bit = (1 << amd->AdaptSCSIID); 2305 amd->AdaptSCSILUN = 0; 2306 /* (eepromBuf[EE_TAG_CMD_NUM]) << 2; */ 2307 amd->ACBFlag = 0; 2308 amd->Gmode2 = amd->eepromBuf[EE_MODE2]; 2309 amd_linkSRB(amd); 2310 for (i = 0; i <= amd->max_id; i++) { 2311 2312 if (amd->AdaptSCSIID != i) { 2313 struct amd_target_info *tinfo; 2314 PEEprom prom; 2315 2316 tinfo = &amd->tinfo[i]; 2317 prom = (PEEprom)&amd->eepromBuf[i << 2]; 2318 if ((prom->EE_MODE1 & EN_DISCONNECT) != 0) { 2319 tinfo->disc_tag |= AMD_USR_DISCENB; 2320 if ((prom->EE_MODE1 & TAG_QUEUING) != 0) 2321 tinfo->disc_tag |= AMD_USR_TAGENB; 2322 } 2323 if ((prom->EE_MODE1 & SYNC_NEGO) != 0) { 2324 tinfo->user.period = 2325 eeprom_period[prom->EE_SPEED]; 2326 tinfo->user.offset = AMD_MAX_SYNC_OFFSET; 2327 } 2328 tinfo->CtrlR1 = amd->AdaptSCSIID; 2329 if ((prom->EE_MODE1 & PARITY_CHK) != 0) 2330 tinfo->CtrlR1 |= PARITY_ERR_REPO; 2331 tinfo->CtrlR3 = FAST_CLK; 2332 tinfo->CtrlR4 = EATER_25NS; 2333 if ((amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) != 0) 2334 tinfo->CtrlR4 |= NEGATE_REQACKDATA; 2335 } 2336 } 2337 amd_write8(amd, SCSITIMEOUTREG, 153); /* 250ms selection timeout */ 2338 /* Conversion factor = 0 , 40MHz clock */ 2339 amd_write8(amd, CLKFACTREG, CLK_FREQ_40MHZ); 2340 /* NOP cmd - clear command register */ 2341 amd_write8(amd, SCSICMDREG, NOP_CMD); 2342 amd_write8(amd, CNTLREG2, EN_FEATURE|EN_SCSI2_CMD); 2343 amd_write8(amd, CNTLREG3, FAST_CLK); 2344 bval = EATER_25NS; 2345 if (amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) { 2346 bval |= NEGATE_REQACKDATA; 2347 } 2348 amd_write8(amd, CNTLREG4, bval); 2349 2350 /* Disable SCSI bus reset interrupt */ 2351 amd_write8(amd, CNTLREG1, DIS_INT_ON_SCSI_RST); 2352 2353 return 0; 2354 } 2355 2356 /* 2357 * attach and init a host adapter 2358 */ 2359 static int 2360 amd_attach(device_t dev) 2361 { 2362 struct cam_devq *devq; /* Device Queue to use for this SIM */ 2363 u_int8_t intstat; 2364 struct amd_softc *amd = device_get_softc(dev); 2365 int unit = device_get_unit(dev); 2366 int rid; 2367 void *ih; 2368 struct resource *irqres; 2369 2370 if (amd_init(dev)) { 2371 if (bootverbose) 2372 printf("amd_attach: amd_init failure!\n"); 2373 return ENXIO; 2374 } 2375 2376 /* Reset Pending INT */ 2377 intstat = amd_read8(amd, INTSTATREG); 2378 2379 /* After setting up the adapter, map our interrupt */ 2380 rid = 0; 2381 irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 2382 RF_SHAREABLE | RF_ACTIVE); 2383 if (irqres == NULL || 2384 bus_setup_intr(dev, irqres, 0, amd_intr, amd, &ih, NULL) 2385 ) { 2386 if (bootverbose) 2387 printf("amd%d: unable to register interrupt handler!\n", 2388 unit); 2389 return ENXIO; 2390 } 2391 2392 /* 2393 * Now let the CAM generic SCSI layer find the SCSI devices on 2394 * the bus * start queue to reset to the idle loop. * 2395 * Create device queue of SIM(s) * (MAX_START_JOB - 1) : 2396 * max_sim_transactions 2397 */ 2398 devq = cam_simq_alloc(MAX_START_JOB); 2399 if (devq == NULL) { 2400 if (bootverbose) 2401 printf("amd_attach: cam_simq_alloc failure!\n"); 2402 return ENXIO; 2403 } 2404 2405 amd->psim = cam_sim_alloc(amd_action, amd_poll, "amd", 2406 amd, amd->unit, 1, MAX_TAGS_CMD_QUEUE, 2407 devq); 2408 cam_simq_release(devq); 2409 if (amd->psim == NULL) { 2410 if (bootverbose) 2411 printf("amd_attach: cam_sim_alloc failure!\n"); 2412 return ENXIO; 2413 } 2414 2415 if (xpt_bus_register(amd->psim, 0) != CAM_SUCCESS) { 2416 cam_sim_free(amd->psim); 2417 if (bootverbose) 2418 printf("amd_attach: xpt_bus_register failure!\n"); 2419 return ENXIO; 2420 } 2421 2422 if (xpt_create_path(&amd->ppath, /* periph */ NULL, 2423 cam_sim_path(amd->psim), CAM_TARGET_WILDCARD, 2424 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 2425 xpt_bus_deregister(cam_sim_path(amd->psim)); 2426 cam_sim_free(amd->psim); 2427 if (bootverbose) 2428 printf("amd_attach: xpt_create_path failure!\n"); 2429 return ENXIO; 2430 } 2431 2432 return 0; 2433 } 2434 2435 static int 2436 amd_probe(device_t dev) 2437 { 2438 if (pci_get_devid(dev) == PCI_DEVICE_ID_AMD53C974) { 2439 device_set_desc(dev, 2440 "Tekram DC390(T)/AMD53c974 SCSI Host Adapter"); 2441 return 0; 2442 } 2443 return ENXIO; 2444 } 2445 2446 static device_method_t amd_methods[] = { 2447 /* Device interface */ 2448 DEVMETHOD(device_probe, amd_probe), 2449 DEVMETHOD(device_attach, amd_attach), 2450 { 0, 0 } 2451 }; 2452 2453 static driver_t amd_driver = { 2454 "amd", amd_methods, sizeof(struct amd_softc) 2455 }; 2456 2457 static devclass_t amd_devclass; 2458 DRIVER_MODULE(amd, pci, amd_driver, amd_devclass, 0, 0); 2459