29 */ 30 31#include "eisa.h" 32#if NEISA > 0 33#include <stddef.h> /* For offsetof() */ 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/malloc.h> 39#include <sys/module.h> 40#include <sys/bus.h> 41 42#include <machine/bus_pio.h> 43#include <machine/bus.h> 44#include <machine/clock.h> 45#include <machine/resource.h> 46#include <sys/rman.h> 47 48#include <cam/cam.h> 49#include <cam/cam_ccb.h> 50#include <cam/cam_sim.h> 51#include <cam/cam_xpt_sim.h> 52#include <cam/cam_debug.h> 53 54#include <cam/scsi/scsi_message.h> 55 56#include <i386/eisa/eisaconf.h> 57 58#include <i386/eisa/ahbreg.h> 59 60#define ccb_ecb_ptr spriv_ptr0 61#define ccb_ahb_ptr spriv_ptr1 62 63#define MIN(a, b) ((a) < (b) ? (a) : (b)) 64 65#define ahb_inb(ahb, port) \ 66 bus_space_read_1((ahb)->tag, (ahb)->bsh, port) 67 68#define ahb_inl(ahb, port) \ 69 bus_space_read_4((ahb)->tag, (ahb)->bsh, port) 70 71#define ahb_outb(ahb, port, value) \ 72 bus_space_write_1((ahb)->tag, (ahb)->bsh, port, value) 73 74#define ahb_outl(ahb, port, value) \ 75 bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value) 76 77static const char *ahbmatch(eisa_id_t type); 78static struct ahb_softc *ahballoc(u_long unit, u_int iobase); 79static void ahbfree(struct ahb_softc *ahb); 80static int ahbreset(struct ahb_softc *ahb); 81static void ahbmapecbs(void *arg, bus_dma_segment_t *segs, 82 int nseg, int error); 83static int ahbxptattach(struct ahb_softc *ahb); 84static void ahbhandleimmed(struct ahb_softc *ahb, 85 u_int32_t mbox, u_int intstat); 86static void ahbcalcresid(struct ahb_softc *ahb, 87 struct ecb *ecb, union ccb *ccb); 88static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox, 89 u_int intstat); 90static void ahbintr(void *arg); 91static bus_dmamap_callback_t ahbexecuteecb; 92static void ahbaction(struct cam_sim *sim, union ccb *ccb); 93static void ahbpoll(struct cam_sim *sim); 94 95/* Our timeout handler */ 96static timeout_t ahbtimeout; 97 98static __inline struct ecb* ahbecbget(struct ahb_softc *ahb); 99static __inline void ahbecbfree(struct ahb_softc* ahb, 100 struct ecb* ecb); 101static __inline u_int32_t ahbecbvtop(struct ahb_softc *ahb, 102 struct ecb *ecb); 103static __inline struct ecb* ahbecbptov(struct ahb_softc *ahb, 104 u_int32_t ecb_addr); 105static __inline u_int32_t ahbstatuspaddr(u_int32_t ecb_paddr); 106static __inline u_int32_t ahbsensepaddr(u_int32_t ecb_paddr); 107static __inline u_int32_t ahbsgpaddr(u_int32_t ecb_paddr); 108static __inline void ahbqueuembox(struct ahb_softc *ahb, 109 u_int32_t mboxval, 110 u_int attn_code); 111 112static __inline struct ecb* 113ahbecbget(struct ahb_softc *ahb) 114{ 115 struct ecb* ecb; 116 int s; 117 118 s = splcam(); 119 if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL) 120 SLIST_REMOVE_HEAD(&ahb->free_ecbs, links); 121 splx(s); 122 123 return (ecb); 124} 125 126static __inline void 127ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb) 128{ 129 int s; 130 131 s = splcam(); 132 ecb->state = ECB_FREE; 133 SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links); 134 splx(s); 135} 136 137static __inline u_int32_t 138ahbecbvtop(struct ahb_softc *ahb, struct ecb *ecb) 139{ 140 return (ahb->ecb_physbase 141 + (u_int32_t)((caddr_t)ecb - (caddr_t)ahb->ecb_array)); 142} 143 144static __inline struct ecb* 145ahbecbptov(struct ahb_softc *ahb, u_int32_t ecb_addr) 146{ 147 return (ahb->ecb_array 148 + ((struct ecb*)ecb_addr - (struct ecb*)ahb->ecb_physbase)); 149} 150 151static __inline u_int32_t 152ahbstatuspaddr(u_int32_t ecb_paddr) 153{ 154 return (ecb_paddr + offsetof(struct ecb, status)); 155} 156 157static __inline u_int32_t 158ahbsensepaddr(u_int32_t ecb_paddr) 159{ 160 return (ecb_paddr + offsetof(struct ecb, sense)); 161} 162 163static __inline u_int32_t 164ahbsgpaddr(u_int32_t ecb_paddr) 165{ 166 return (ecb_paddr + offsetof(struct ecb, sg_list)); 167} 168 169static __inline void 170ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code) 171{ 172 u_int loopmax = 300; 173 while (--loopmax) { 174 u_int status; 175 176 status = ahb_inb(ahb, HOSTSTAT); 177 if ((status & (HOSTSTAT_MBOX_EMPTY|HOSTSTAT_BUSY)) 178 == HOSTSTAT_MBOX_EMPTY) 179 break; 180 DELAY(20); 181 } 182 if (loopmax == 0) 183 panic("ahb%ld: adapter not taking commands\n", ahb->unit); 184 185 ahb_outl(ahb, MBOXOUT0, mboxval); 186 ahb_outb(ahb, ATTN, attn_code); 187} 188 189static const char * 190ahbmatch(eisa_id_t type) 191{ 192 switch(type & 0xfffffe00) { 193 case EISA_DEVICE_ID_ADAPTEC_1740: 194 return ("Adaptec 174x SCSI host adapter"); 195 break; 196 default: 197 break; 198 } 199 return (NULL); 200} 201 202static int 203ahbprobe(device_t dev) 204{ 205 const char *desc; 206 u_int32_t iobase; 207 u_int32_t irq; 208 u_int8_t intdef; 209 int shared; 210 211 desc = ahbmatch(eisa_get_id(dev)); 212 if (!desc) 213 return (ENXIO); 214 device_set_desc(dev, desc); 215 216 iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + 217 AHB_EISA_SLOT_OFFSET; 218 219 eisa_add_iospace(dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE); 220 221 intdef = inb(INTDEF + iobase); 222 switch (intdef & 0x7) { 223 case INT9: 224 irq = 9; 225 break; 226 case INT10: 227 irq = 10; 228 break; 229 case INT11: 230 irq = 11; 231 break; 232 case INT12: 233 irq = 12; 234 break; 235 case INT14: 236 irq = 14; 237 break; 238 case INT15: 239 irq = 15; 240 break; 241 default: 242 printf("Adaptec 174X at slot %d: illegal " 243 "irq setting %d\n", eisa_get_slot(dev), 244 (intdef & 0x7)); 245 irq = 0; 246 break; 247 } 248 if (irq == 0) 249 return ENXIO; 250 251 shared = (inb(INTDEF + iobase) & INTLEVEL) ? 252 EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; 253 254 eisa_add_intr(dev, irq, shared); 255 256 return 0; 257} 258 259static int 260ahbattach(device_t dev) 261{ 262 /* 263 * find unit and check we have that many defined 264 */ 265 struct ahb_softc *ahb; 266 struct ecb* next_ecb; 267 struct resource *io = 0; 268 struct resource *irq = 0; 269 int rid; 270 void *ih; 271 272 rid = 0; 273 io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 274 0, ~0, 1, RF_ACTIVE); 275 if (!io) { 276 device_printf(dev, "No I/O space?!\n"); 277 return ENOMEM; 278 } 279 280 if ((ahb = ahballoc(device_get_unit(dev), rman_get_start(io))) == NULL) { 281 goto error_exit2; 282 } 283 284 if (ahbreset(ahb) != 0) 285 goto error_exit; 286 287 rid = 0; 288 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 289 0, ~0, 1, RF_ACTIVE); 290 if (!irq) { 291 device_printf(dev, "Can't allocate interrupt\n"); 292 goto error_exit; 293 } 294 295 /* 296 * Create our DMA tags. These tags define the kinds of device 297 * accessable memory allocations and memory mappings we will 298 * need to perform during normal operation. 299 */ 300 /* DMA tag for mapping buffers into device visible space. */ 301 /* XXX Should be a child of the EISA bus dma tag */
| 29 */ 30 31#include "eisa.h" 32#if NEISA > 0 33#include <stddef.h> /* For offsetof() */ 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/malloc.h> 39#include <sys/module.h> 40#include <sys/bus.h> 41 42#include <machine/bus_pio.h> 43#include <machine/bus.h> 44#include <machine/clock.h> 45#include <machine/resource.h> 46#include <sys/rman.h> 47 48#include <cam/cam.h> 49#include <cam/cam_ccb.h> 50#include <cam/cam_sim.h> 51#include <cam/cam_xpt_sim.h> 52#include <cam/cam_debug.h> 53 54#include <cam/scsi/scsi_message.h> 55 56#include <i386/eisa/eisaconf.h> 57 58#include <i386/eisa/ahbreg.h> 59 60#define ccb_ecb_ptr spriv_ptr0 61#define ccb_ahb_ptr spriv_ptr1 62 63#define MIN(a, b) ((a) < (b) ? (a) : (b)) 64 65#define ahb_inb(ahb, port) \ 66 bus_space_read_1((ahb)->tag, (ahb)->bsh, port) 67 68#define ahb_inl(ahb, port) \ 69 bus_space_read_4((ahb)->tag, (ahb)->bsh, port) 70 71#define ahb_outb(ahb, port, value) \ 72 bus_space_write_1((ahb)->tag, (ahb)->bsh, port, value) 73 74#define ahb_outl(ahb, port, value) \ 75 bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value) 76 77static const char *ahbmatch(eisa_id_t type); 78static struct ahb_softc *ahballoc(u_long unit, u_int iobase); 79static void ahbfree(struct ahb_softc *ahb); 80static int ahbreset(struct ahb_softc *ahb); 81static void ahbmapecbs(void *arg, bus_dma_segment_t *segs, 82 int nseg, int error); 83static int ahbxptattach(struct ahb_softc *ahb); 84static void ahbhandleimmed(struct ahb_softc *ahb, 85 u_int32_t mbox, u_int intstat); 86static void ahbcalcresid(struct ahb_softc *ahb, 87 struct ecb *ecb, union ccb *ccb); 88static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox, 89 u_int intstat); 90static void ahbintr(void *arg); 91static bus_dmamap_callback_t ahbexecuteecb; 92static void ahbaction(struct cam_sim *sim, union ccb *ccb); 93static void ahbpoll(struct cam_sim *sim); 94 95/* Our timeout handler */ 96static timeout_t ahbtimeout; 97 98static __inline struct ecb* ahbecbget(struct ahb_softc *ahb); 99static __inline void ahbecbfree(struct ahb_softc* ahb, 100 struct ecb* ecb); 101static __inline u_int32_t ahbecbvtop(struct ahb_softc *ahb, 102 struct ecb *ecb); 103static __inline struct ecb* ahbecbptov(struct ahb_softc *ahb, 104 u_int32_t ecb_addr); 105static __inline u_int32_t ahbstatuspaddr(u_int32_t ecb_paddr); 106static __inline u_int32_t ahbsensepaddr(u_int32_t ecb_paddr); 107static __inline u_int32_t ahbsgpaddr(u_int32_t ecb_paddr); 108static __inline void ahbqueuembox(struct ahb_softc *ahb, 109 u_int32_t mboxval, 110 u_int attn_code); 111 112static __inline struct ecb* 113ahbecbget(struct ahb_softc *ahb) 114{ 115 struct ecb* ecb; 116 int s; 117 118 s = splcam(); 119 if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL) 120 SLIST_REMOVE_HEAD(&ahb->free_ecbs, links); 121 splx(s); 122 123 return (ecb); 124} 125 126static __inline void 127ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb) 128{ 129 int s; 130 131 s = splcam(); 132 ecb->state = ECB_FREE; 133 SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links); 134 splx(s); 135} 136 137static __inline u_int32_t 138ahbecbvtop(struct ahb_softc *ahb, struct ecb *ecb) 139{ 140 return (ahb->ecb_physbase 141 + (u_int32_t)((caddr_t)ecb - (caddr_t)ahb->ecb_array)); 142} 143 144static __inline struct ecb* 145ahbecbptov(struct ahb_softc *ahb, u_int32_t ecb_addr) 146{ 147 return (ahb->ecb_array 148 + ((struct ecb*)ecb_addr - (struct ecb*)ahb->ecb_physbase)); 149} 150 151static __inline u_int32_t 152ahbstatuspaddr(u_int32_t ecb_paddr) 153{ 154 return (ecb_paddr + offsetof(struct ecb, status)); 155} 156 157static __inline u_int32_t 158ahbsensepaddr(u_int32_t ecb_paddr) 159{ 160 return (ecb_paddr + offsetof(struct ecb, sense)); 161} 162 163static __inline u_int32_t 164ahbsgpaddr(u_int32_t ecb_paddr) 165{ 166 return (ecb_paddr + offsetof(struct ecb, sg_list)); 167} 168 169static __inline void 170ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code) 171{ 172 u_int loopmax = 300; 173 while (--loopmax) { 174 u_int status; 175 176 status = ahb_inb(ahb, HOSTSTAT); 177 if ((status & (HOSTSTAT_MBOX_EMPTY|HOSTSTAT_BUSY)) 178 == HOSTSTAT_MBOX_EMPTY) 179 break; 180 DELAY(20); 181 } 182 if (loopmax == 0) 183 panic("ahb%ld: adapter not taking commands\n", ahb->unit); 184 185 ahb_outl(ahb, MBOXOUT0, mboxval); 186 ahb_outb(ahb, ATTN, attn_code); 187} 188 189static const char * 190ahbmatch(eisa_id_t type) 191{ 192 switch(type & 0xfffffe00) { 193 case EISA_DEVICE_ID_ADAPTEC_1740: 194 return ("Adaptec 174x SCSI host adapter"); 195 break; 196 default: 197 break; 198 } 199 return (NULL); 200} 201 202static int 203ahbprobe(device_t dev) 204{ 205 const char *desc; 206 u_int32_t iobase; 207 u_int32_t irq; 208 u_int8_t intdef; 209 int shared; 210 211 desc = ahbmatch(eisa_get_id(dev)); 212 if (!desc) 213 return (ENXIO); 214 device_set_desc(dev, desc); 215 216 iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + 217 AHB_EISA_SLOT_OFFSET; 218 219 eisa_add_iospace(dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE); 220 221 intdef = inb(INTDEF + iobase); 222 switch (intdef & 0x7) { 223 case INT9: 224 irq = 9; 225 break; 226 case INT10: 227 irq = 10; 228 break; 229 case INT11: 230 irq = 11; 231 break; 232 case INT12: 233 irq = 12; 234 break; 235 case INT14: 236 irq = 14; 237 break; 238 case INT15: 239 irq = 15; 240 break; 241 default: 242 printf("Adaptec 174X at slot %d: illegal " 243 "irq setting %d\n", eisa_get_slot(dev), 244 (intdef & 0x7)); 245 irq = 0; 246 break; 247 } 248 if (irq == 0) 249 return ENXIO; 250 251 shared = (inb(INTDEF + iobase) & INTLEVEL) ? 252 EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; 253 254 eisa_add_intr(dev, irq, shared); 255 256 return 0; 257} 258 259static int 260ahbattach(device_t dev) 261{ 262 /* 263 * find unit and check we have that many defined 264 */ 265 struct ahb_softc *ahb; 266 struct ecb* next_ecb; 267 struct resource *io = 0; 268 struct resource *irq = 0; 269 int rid; 270 void *ih; 271 272 rid = 0; 273 io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 274 0, ~0, 1, RF_ACTIVE); 275 if (!io) { 276 device_printf(dev, "No I/O space?!\n"); 277 return ENOMEM; 278 } 279 280 if ((ahb = ahballoc(device_get_unit(dev), rman_get_start(io))) == NULL) { 281 goto error_exit2; 282 } 283 284 if (ahbreset(ahb) != 0) 285 goto error_exit; 286 287 rid = 0; 288 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 289 0, ~0, 1, RF_ACTIVE); 290 if (!irq) { 291 device_printf(dev, "Can't allocate interrupt\n"); 292 goto error_exit; 293 } 294 295 /* 296 * Create our DMA tags. These tags define the kinds of device 297 * accessable memory allocations and memory mappings we will 298 * need to perform during normal operation. 299 */ 300 /* DMA tag for mapping buffers into device visible space. */ 301 /* XXX Should be a child of the EISA bus dma tag */
|
316 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 317 /*highaddr*/BUS_SPACE_MAXADDR, 318 /*filter*/NULL, /*filterarg*/NULL, 319 (AHB_NECB * sizeof(struct ecb)) 320 + sizeof(*ahb->ha_inq_data), 321 /*nsegments*/1, 322 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 323 /*flags*/0, &ahb->ecb_dmat) != 0) 324 goto error_exit; 325 326 ahb->init_level++; 327 328 /* Allocation for our ccbs */ 329 if (bus_dmamem_alloc(ahb->ecb_dmat, (void **)&ahb->ecb_array, 330 BUS_DMA_NOWAIT, &ahb->ecb_dmamap) != 0) 331 goto error_exit; 332 333 ahb->ha_inq_data = (struct ha_inquiry_data *)&ahb->ecb_array[AHB_NECB]; 334 335 ahb->init_level++; 336 337 /* And permanently map them */ 338 bus_dmamap_load(ahb->ecb_dmat, ahb->ecb_dmamap, 339 ahb->ecb_array, AHB_NSEG * sizeof(struct ecb), 340 ahbmapecbs, ahb, /*flags*/0); 341 342 ahb->init_level++; 343 344 /* Allocate the buffer dmamaps for each of our ECBs */ 345 bzero(ahb->ecb_array, (AHB_NECB * sizeof(struct ecb)) 346 + sizeof(*ahb->ha_inq_data)); 347 next_ecb = ahb->ecb_array; 348 while (ahb->num_ecbs < AHB_NECB) { 349 u_int32_t ecb_paddr; 350 351 if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0, 352 &next_ecb->dmamap)) 353 break; 354 ecb_paddr = ahbecbvtop(ahb, next_ecb); 355 next_ecb->hecb.status_ptr = ahbstatuspaddr(ecb_paddr); 356 next_ecb->hecb.sense_ptr = ahbsensepaddr(ecb_paddr); 357 ahb->num_ecbs++; 358 ahbecbfree(ahb, next_ecb); 359 next_ecb++; 360 } 361 362 if (ahb->num_ecbs == 0) 363 goto error_exit; 364 365 ahb->init_level++; 366 367 /* 368 * Now that we know we own the resources we need, register 369 * our bus with the XPT. 370 */ 371 if (ahbxptattach(ahb)) 372 goto error_exit; 373 374 /* Enable our interrupt */ 375 bus_setup_intr(dev, irq, INTR_TYPE_CAM, ahbintr, ahb, &ih); 376 return (0); 377 378error_exit: 379 /* 380 * The board's IRQ line will not be left enabled 381 * if we can't intialize correctly, so its safe 382 * to release the irq. 383 */ 384 ahbfree(ahb); 385error_exit2: 386 if (io) 387 bus_release_resource(dev, SYS_RES_IOPORT, 0, io); 388 if (irq) 389 bus_release_resource(dev, SYS_RES_IRQ, 0, irq); 390 return (-1); 391} 392 393static struct ahb_softc * 394ahballoc(u_long unit, u_int iobase) 395{ 396 struct ahb_softc *ahb; 397 398 /* 399 * Allocate a storage area for us 400 */ 401 ahb = malloc(sizeof(struct ahb_softc), M_DEVBUF, M_NOWAIT); 402 if (!ahb) { 403 printf("ahb%ld: cannot malloc!\n", unit); 404 return (NULL); 405 } 406 bzero(ahb, sizeof(struct ahb_softc)); 407 SLIST_INIT(&ahb->free_ecbs); 408 LIST_INIT(&ahb->pending_ccbs); 409 ahb->unit = unit; 410 ahb->tag = I386_BUS_SPACE_IO; 411 ahb->bsh = iobase; 412 ahb->disc_permitted = ~0; 413 ahb->tags_permitted = ~0; 414 415 return (ahb); 416} 417 418static void 419ahbfree(struct ahb_softc *ahb) 420{ 421 switch (ahb->init_level) { 422 default: 423 case 4: 424 bus_dmamap_unload(ahb->ecb_dmat, ahb->ecb_dmamap); 425 case 3: 426 bus_dmamem_free(ahb->ecb_dmat, ahb->ecb_array, 427 ahb->ecb_dmamap); 428 bus_dmamap_destroy(ahb->ecb_dmat, ahb->ecb_dmamap); 429 case 2: 430 bus_dma_tag_destroy(ahb->ecb_dmat); 431 case 1: 432 bus_dma_tag_destroy(ahb->buffer_dmat); 433 case 0: 434 } 435 free(ahb, M_DEVBUF); 436} 437 438/* 439 * reset board, If it doesn't respond, return failure 440 */ 441static int 442ahbreset(struct ahb_softc *ahb) 443{ 444 int wait = 1000; /* 1 sec enough? */ 445 int test; 446 447 if ((ahb_inb(ahb, PORTADDR) & PORTADDR_ENHANCED) == 0) { 448 printf("ahb_reset: Controller not in enhanced mode\n"); 449 return (-1); 450 } 451 452 ahb_outb(ahb, CONTROL, CNTRL_HARD_RST); 453 DELAY(1000); 454 ahb_outb(ahb, CONTROL, 0); 455 while (--wait) { 456 DELAY(1000); 457 if ((ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_BUSY) == 0) 458 break; 459 } 460 461 if (wait == 0) { 462 printf("ahbreset: No answer from aha1742 board\n"); 463 return (-1); 464 } 465 if ((test = ahb_inb(ahb, MBOXIN0)) != 0) { 466 printf("ahb_reset: self test failed, val = 0x%x\n", test); 467 return (-1); 468 } 469 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { 470 ahb_outb(ahb, CONTROL, CNTRL_CLRINT); 471 DELAY(10000); 472 } 473 return (0); 474} 475 476static void 477ahbmapecbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 478{ 479 struct ahb_softc* ahb; 480 481 ahb = (struct ahb_softc*)arg; 482 ahb->ecb_physbase = segs->ds_addr; 483 /* 484 * Space for adapter inquiry information is on the 485 * tail of the ecb array. 486 */ 487 ahb->ha_inq_physbase = ahbecbvtop(ahb, &ahb->ecb_array[AHB_NECB]); 488} 489 490static int 491ahbxptattach(struct ahb_softc *ahb) 492{ 493 struct cam_devq *devq; 494 struct ecb *ecb; 495 u_int i; 496 497 /* Remeber who are we on the scsi bus */ 498 ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID; 499 500 /* Use extended translation?? */ 501 ahb->extended_trans = ahb_inb(ahb, RESV1) & EXTENDED_TRANS; 502 503 /* Fetch adapter inquiry data */ 504 ecb = ahbecbget(ahb); /* Always succeeds - no outstanding commands */ 505 ecb->hecb.opcode = ECBOP_READ_HA_INQDATA; 506 ecb->hecb.flag_word1 = FW1_SUPPRESS_URUN_ERR|FW1_ERR_STATUS_BLK_ONLY; 507 ecb->hecb.data_ptr = ahb->ha_inq_physbase; 508 ecb->hecb.data_len = sizeof(struct ha_inquiry_data); 509 ecb->hecb.sense_ptr = 0; 510 ecb->state = ECB_ACTIVE; 511 512 /* Tell the adapter about this command */ 513 ahbqueuembox(ahb, ahbecbvtop(ahb, ecb), 514 ATTN_STARTECB|ahb->scsi_id); 515 516 /* Poll for interrupt completion */ 517 for (i = 1000; ecb->state != ECB_FREE && i != 0; i--) { 518 ahbintr(ahb); 519 DELAY(1000); 520 } 521 522 ahb->num_ecbs = MIN(ahb->num_ecbs, 523 ahb->ha_inq_data->scsi_data.reserved[1]); 524 printf("ahb%ld: %.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n", 525 ahb->unit, ahb->ha_inq_data->scsi_data.product, 526 (ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential" 527 : "Single Ended", 528 ahb->ha_inq_data->scsi_data.revision, 529 ahb->scsi_id, ahb->num_ecbs); 530 531 /* Restore sense paddr for future CCB clients */ 532 ecb->hecb.sense_ptr = ahbsensepaddr(ahbecbvtop(ahb, ecb)); 533 534 ahbecbfree(ahb, ecb); 535 536 /* 537 * Create the device queue for our SIM. 538 */ 539 devq = cam_simq_alloc(ahb->num_ecbs); 540 if (devq == NULL) 541 return (ENOMEM); 542 543 /* 544 * Construct our SIM entry 545 */ 546 ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb, ahb->unit, 547 2, ahb->num_ecbs, devq); 548 if (ahb->sim == NULL) { 549 cam_simq_free(devq); 550 return (ENOMEM); 551 } 552 553 if (xpt_bus_register(ahb->sim, 0) != CAM_SUCCESS) { 554 cam_sim_free(ahb->sim, /*free_devq*/TRUE); 555 return (ENXIO); 556 } 557 558 if (xpt_create_path(&ahb->path, /*periph*/NULL, 559 cam_sim_path(ahb->sim), CAM_TARGET_WILDCARD, 560 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 561 xpt_bus_deregister(cam_sim_path(ahb->sim)); 562 cam_sim_free(ahb->sim, /*free_devq*/TRUE); 563 return (ENXIO); 564 } 565 566 /* 567 * Allow the board to generate interrupts. 568 */ 569 ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN); 570 571 return (0); 572} 573 574static void 575ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) 576{ 577 struct ccb_hdr *ccb_h; 578 u_int target_id; 579 580 if (ahb->immed_cmd == 0) { 581 printf("ahb%ld: Immediate Command complete with no " 582 " pending command\n", ahb->unit); 583 return; 584 } 585 586 target_id = intstat & INTSTAT_TARGET_MASK; 587 588 ccb_h = LIST_FIRST(&ahb->pending_ccbs); 589 while (ccb_h != NULL) { 590 struct ecb *pending_ecb; 591 union ccb *ccb; 592 593 pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; 594 ccb = pending_ecb->ccb; 595 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 596 if (ccb->ccb_h.target_id == target_id 597 || target_id == ahb->scsi_id) { 598 untimeout(ahbtimeout, pending_ecb, 599 ccb->ccb_h.timeout_ch); 600 LIST_REMOVE(&ccb->ccb_h, sim_links.le); 601 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) 602 bus_dmamap_unload(ahb->buffer_dmat, 603 pending_ecb->dmamap); 604 if (pending_ecb == ahb->immed_ecb) 605 ccb->ccb_h.status = 606 CAM_CMD_TIMEOUT|CAM_RELEASE_SIMQ; 607 else if (target_id == ahb->scsi_id) 608 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 609 else 610 ccb->ccb_h.status = CAM_BDR_SENT; 611 ahbecbfree(ahb, pending_ecb); 612 xpt_done(ccb); 613 } else if (ahb->immed_ecb != NULL) { 614 /* Re-instate timeout */ 615 ccb->ccb_h.timeout_ch = 616 timeout(ahbtimeout, (caddr_t)pending_ecb, 617 (ccb->ccb_h.timeout * hz) / 1000); 618 } 619 } 620 621 if (ahb->immed_ecb != NULL) { 622 ahb->immed_ecb = NULL; 623 printf("ahb%ld: No longer in timeout\n", ahb->unit); 624 } else if (target_id == ahb->scsi_id) 625 printf("ahb%ld: SCSI Bus Reset Delivered\n", ahb->unit); 626 else 627 printf("ahb%ld: Bus Device Reset Delibered to target %d\n", 628 ahb->unit, target_id); 629 630 ahb->immed_cmd = 0; 631} 632 633static void 634ahbcalcresid(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) 635{ 636 if (ecb->status.data_overrun != 0) { 637 /* 638 * Overrun Condition. The hardware doesn't 639 * provide a meaningful byte count in this case 640 * (the residual is always 0). Tell the XPT 641 * layer about the error. 642 */ 643 ccb->ccb_h.status = CAM_DATA_RUN_ERR; 644 } else { 645 ccb->csio.resid = ecb->status.resid_count; 646 647 if ((ecb->hecb.flag_word1 & FW1_SG_ECB) != 0) { 648 /* 649 * For S/G transfers, the adapter provides a pointer 650 * to the address in the last S/G element used and a 651 * residual for that element. So, we need to sum up 652 * the elements that follow it in order to get a real 653 * residual number. If we have an overrun, the residual 654 * reported will be 0 and we already know that all S/G 655 * segments have been exhausted, so we can skip this 656 * step. 657 */ 658 ahb_sg_t *sg; 659 int num_sg; 660 661 num_sg = ecb->hecb.data_len / sizeof(ahb_sg_t); 662 663 /* Find the S/G the adapter was working on */ 664 for (sg = ecb->sg_list; 665 num_sg != 0 && sg->addr != ecb->status.resid_addr; 666 num_sg--, sg++) 667 ; 668 669 /* Skip it */ 670 num_sg--; 671 sg++; 672 673 /* Sum the rest */ 674 for (; num_sg != 0; num_sg--, sg++) 675 ccb->csio.resid += sg->len; 676 } 677 /* Underruns are not errors */ 678 ccb->ccb_h.status = CAM_REQ_CMP; 679 } 680} 681 682static void 683ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) 684{ 685 struct hardware_ecb *hecb; 686 struct ecb_status *status; 687 688 hecb = &ecb->hecb; 689 status = &ecb->status; 690 switch (status->ha_status) { 691 case HS_OK: 692 ccb->csio.scsi_status = status->scsi_status; 693 if (status->scsi_status != 0) { 694 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 695 if (status->sense_stored) { 696 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 697 ccb->csio.sense_resid = 698 ccb->csio.sense_len - status->sense_len; 699 bcopy(&ecb->sense, &ccb->csio.sense_data, 700 status->sense_len); 701 } 702 } 703 break; 704 case HS_TARGET_NOT_ASSIGNED: 705 ccb->ccb_h.status = CAM_PATH_INVALID; 706 break; 707 case HS_SEL_TIMEOUT: 708 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 709 break; 710 case HS_DATA_RUN_ERR: 711 ahbcalcresid(ahb, ecb, ccb); 712 break; 713 case HS_UNEXPECTED_BUSFREE: 714 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 715 break; 716 case HS_INVALID_PHASE: 717 ccb->ccb_h.status = CAM_SEQUENCE_FAIL; 718 break; 719 case HS_REQUEST_SENSE_FAILED: 720 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; 721 break; 722 case HS_TAG_MSG_REJECTED: 723 { 724 struct ccb_trans_settings neg; 725 726 xpt_print_path(ccb->ccb_h.path); 727 printf("refuses tagged commands. Performing " 728 "non-tagged I/O\n"); 729 neg.flags = 0; 730 neg.valid = CCB_TRANS_TQ_VALID; 731 xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); 732 xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); 733 ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id); 734 ccb->ccb_h.status = CAM_MSG_REJECT_REC; 735 break; 736 } 737 case HS_FIRMWARE_LOAD_REQ: 738 case HS_HARDWARE_ERR: 739 /* 740 * Tell the system that the Adapter 741 * is no longer functional. 742 */ 743 ccb->ccb_h.status = CAM_NO_HBA; 744 break; 745 case HS_CMD_ABORTED_HOST: 746 case HS_CMD_ABORTED_ADAPTER: 747 case HS_ATN_TARGET_FAILED: 748 case HS_SCSI_RESET_ADAPTER: 749 case HS_SCSI_RESET_INCOMING: 750 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 751 break; 752 case HS_INVALID_ECB_PARAM: 753 printf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n", 754 ahb->unit, hecb->opcode, hecb->flag_word1, hecb->flag_word2); 755 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 756 break; 757 case HS_DUP_TCB_RECEIVED: 758 case HS_INVALID_OPCODE: 759 case HS_INVALID_CMD_LINK: 760 case HS_PROGRAM_CKSUM_ERROR: 761 panic("ahb%ld: Can't happen host status %x occurred", 762 ahb->unit, status->ha_status); 763 break; 764 } 765 if (ccb->ccb_h.status != CAM_REQ_CMP) { 766 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 767 ccb->ccb_h.status |= CAM_DEV_QFRZN; 768 } 769} 770 771static void 772ahbdone(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) 773{ 774 struct ecb *ecb; 775 union ccb *ccb; 776 777 ecb = ahbecbptov(ahb, mbox); 778 779 if ((ecb->state & ECB_ACTIVE) == 0) 780 panic("ecb not active"); 781 782 ccb = ecb->ccb; 783 784 if (ccb != NULL) { 785 untimeout(ahbtimeout, ecb, ccb->ccb_h.timeout_ch); 786 LIST_REMOVE(&ccb->ccb_h, sim_links.le); 787 788 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 789 bus_dmasync_op_t op; 790 791 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 792 op = BUS_DMASYNC_POSTREAD; 793 else 794 op = BUS_DMASYNC_POSTWRITE; 795 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); 796 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); 797 } 798 799 if ((intstat & INTSTAT_MASK) == INTSTAT_ECB_OK) { 800 ccb->ccb_h.status = CAM_REQ_CMP; 801 ccb->csio.resid = 0; 802 } else { 803 ahbprocesserror(ahb, ecb, ccb); 804 } 805 ahbecbfree(ahb, ecb); 806 xpt_done(ccb); 807 } else { 808 /* Non CCB Command */ 809 if ((intstat & INTSTAT_MASK) != INTSTAT_ECB_OK) { 810 printf("ahb%ld: Command 0%x Failed %x:%x:%x\n", 811 ahb->unit, ecb->hecb.opcode, 812 *((u_int16_t*)&ecb->status), 813 ecb->status.ha_status, ecb->status.resid_count); 814 } 815 /* Client owns this ECB and will release it. */ 816 } 817} 818 819/* 820 * Catch an interrupt from the adaptor 821 */ 822static void 823ahbintr(void *arg) 824{ 825 struct ahb_softc *ahb; 826 u_int intstat; 827 u_int32_t mbox; 828 829 ahb = (struct ahb_softc *)arg; 830 831 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { 832 /* 833 * Fetch information about this interrupt. 834 */ 835 intstat = ahb_inb(ahb, INTSTAT); 836 mbox = ahb_inl(ahb, MBOXIN0); 837 838 /* 839 * Reset interrupt latch. 840 */ 841 ahb_outb(ahb, CONTROL, CNTRL_CLRINT); 842 843 /* 844 * Process the completed operation 845 */ 846 switch (intstat & INTSTAT_MASK) { 847 case INTSTAT_ECB_OK: 848 case INTSTAT_ECB_CMPWRETRY: 849 case INTSTAT_ECB_CMPWERR: 850 ahbdone(ahb, mbox, intstat); 851 break; 852 case INTSTAT_AEN_OCCURED: 853 if ((intstat & INTSTAT_TARGET_MASK) == ahb->scsi_id) { 854 /* Bus Reset */ 855 xpt_print_path(ahb->path); 856 switch (mbox) { 857 case HS_SCSI_RESET_ADAPTER: 858 printf("Host Adapter Initiated " 859 "Bus Reset occurred\n"); 860 break; 861 case HS_SCSI_RESET_INCOMING: 862 printf("Bus Reset Initiated " 863 "by another device occurred\n"); 864 break; 865 } 866 /* Notify the XPT */ 867 xpt_async(AC_BUS_RESET, ahb->path, NULL); 868 break; 869 } 870 printf("Unsupported initiator selection AEN occured\n"); 871 break; 872 case INTSTAT_IMMED_OK: 873 case INTSTAT_IMMED_ERR: 874 ahbhandleimmed(ahb, mbox, intstat); 875 break; 876 case INTSTAT_HW_ERR: 877 panic("Unrecoverable hardware Error Occurred\n"); 878 } 879 } 880} 881 882static void 883ahbexecuteecb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 884{ 885 struct ecb *ecb; 886 union ccb *ccb; 887 struct ahb_softc *ahb; 888 u_int32_t ecb_paddr; 889 int s; 890 891 ecb = (struct ecb *)arg; 892 ccb = ecb->ccb; 893 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; 894 895 if (error != 0) { 896 if (error != EFBIG) 897 printf("ahb%ld: Unexepected error 0x%x returned from " 898 "bus_dmamap_load\n", ahb->unit, error); 899 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 900 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 901 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 902 } 903 ahbecbfree(ahb, ecb); 904 xpt_done(ccb); 905 return; 906 } 907 908 ecb_paddr = ahbecbvtop(ahb, ecb); 909 910 if (nseg != 0) { 911 ahb_sg_t *sg; 912 bus_dma_segment_t *end_seg; 913 bus_dmasync_op_t op; 914 915 end_seg = dm_segs + nseg; 916 917 /* Copy the segments into our SG list */ 918 sg = ecb->sg_list; 919 while (dm_segs < end_seg) { 920 sg->addr = dm_segs->ds_addr; 921 sg->len = dm_segs->ds_len; 922 sg++; 923 dm_segs++; 924 } 925 926 if (nseg > 1) { 927 ecb->hecb.flag_word1 |= FW1_SG_ECB; 928 ecb->hecb.data_ptr = ahbsgpaddr(ecb_paddr); 929 ecb->hecb.data_len = sizeof(ahb_sg_t) * nseg; 930 } else { 931 ecb->hecb.data_ptr = ecb->sg_list->addr; 932 ecb->hecb.data_len = ecb->sg_list->len; 933 } 934 935 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 936/* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */ 937 op = BUS_DMASYNC_PREREAD; 938 } else { 939 op = BUS_DMASYNC_PREWRITE; 940 } 941 /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */ 942 943 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); 944 945 } else { 946 ecb->hecb.data_ptr = 0; 947 ecb->hecb.data_len = 0; 948 } 949 950 s = splcam(); 951 952 /* 953 * Last time we need to check if this CCB needs to 954 * be aborted. 955 */ 956 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 957 if (nseg != 0) 958 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); 959 ahbecbfree(ahb, ecb); 960 xpt_done(ccb); 961 splx(s); 962 return; 963 } 964 965 ecb->state = ECB_ACTIVE; 966 ccb->ccb_h.status |= CAM_SIM_QUEUED; 967 LIST_INSERT_HEAD(&ahb->pending_ccbs, &ccb->ccb_h, sim_links.le); 968 969 /* Tell the adapter about this command */ 970 ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id); 971 972 ccb->ccb_h.timeout_ch = timeout(ahbtimeout, (caddr_t)ecb, 973 (ccb->ccb_h.timeout * hz) / 1000); 974 splx(s); 975} 976 977static void 978ahbaction(struct cam_sim *sim, union ccb *ccb) 979{ 980 struct ahb_softc *ahb; 981 982 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahbaction\n")); 983 984 ahb = (struct ahb_softc *)cam_sim_softc(sim); 985 986 switch (ccb->ccb_h.func_code) { 987 /* Common cases first */ 988 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 989 { 990 struct ecb *ecb; 991 struct hardware_ecb *hecb; 992 993 /* 994 * get an ecb to use. 995 */ 996 if ((ecb = ahbecbget(ahb)) == NULL) { 997 /* Should never occur */ 998 panic("Failed to get an ecb"); 999 } 1000 1001 /* 1002 * So we can find the ECB when an abort is requested 1003 */ 1004 ecb->ccb = ccb; 1005 ccb->ccb_h.ccb_ecb_ptr = ecb; 1006 ccb->ccb_h.ccb_ahb_ptr = ahb; 1007 1008 /* 1009 * Put all the arguments for the xfer in the ecb 1010 */ 1011 hecb = &ecb->hecb; 1012 hecb->opcode = ECBOP_INITIATOR_SCSI_CMD; 1013 hecb->flag_word1 = FW1_AUTO_REQUEST_SENSE 1014 | FW1_ERR_STATUS_BLK_ONLY; 1015 hecb->flag_word2 = ccb->ccb_h.target_lun 1016 | FW2_NO_RETRY_ON_BUSY; 1017 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 1018 hecb->flag_word2 |= FW2_TAG_ENB 1019 | ((ccb->csio.tag_action & 0x3) 1020 << FW2_TAG_TYPE_SHIFT); 1021 } 1022 if ((ccb->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) 1023 hecb->flag_word2 |= FW2_DISABLE_DISC; 1024 hecb->sense_len = ccb->csio.sense_len; 1025 hecb->cdb_len = ccb->csio.cdb_len; 1026 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 1027 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { 1028 bcopy(ccb->csio.cdb_io.cdb_ptr, 1029 hecb->cdb, hecb->cdb_len); 1030 } else { 1031 /* I guess I could map it in... */ 1032 ccb->ccb_h.status = CAM_REQ_INVALID; 1033 ahbecbfree(ahb, ecb); 1034 xpt_done(ccb); 1035 return; 1036 } 1037 } else { 1038 bcopy(ccb->csio.cdb_io.cdb_bytes, 1039 hecb->cdb, hecb->cdb_len); 1040 } 1041 1042 /* 1043 * If we have any data to send with this command, 1044 * map it into bus space. 1045 */ 1046 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1047 if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { 1048 /* 1049 * We've been given a pointer 1050 * to a single buffer. 1051 */ 1052 if ((ccb->ccb_h.flags & CAM_DATA_PHYS)==0) { 1053 int s; 1054 int error; 1055 1056 s = splsoftvm(); 1057 error = bus_dmamap_load( 1058 ahb->buffer_dmat, 1059 ecb->dmamap, 1060 ccb->csio.data_ptr, 1061 ccb->csio.dxfer_len, 1062 ahbexecuteecb, 1063 ecb, /*flags*/0); 1064 if (error == EINPROGRESS) { 1065 /* 1066 * So as to maintain ordering, 1067 * freeze the controller queue 1068 * until our mapping is 1069 * returned. 1070 */ 1071 xpt_freeze_simq(ahb->sim, 1); 1072 ccb->ccb_h.status |= 1073 CAM_RELEASE_SIMQ; 1074 } 1075 splx(s); 1076 } else { 1077 struct bus_dma_segment seg; 1078 1079 /* Pointer to physical buffer */ 1080 seg.ds_addr = 1081 (bus_addr_t)ccb->csio.data_ptr; 1082 seg.ds_len = ccb->csio.dxfer_len; 1083 ahbexecuteecb(ecb, &seg, 1, 0); 1084 } 1085 } else { 1086 struct bus_dma_segment *segs; 1087 1088 if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) 1089 panic("ahbaction - Physical segment " 1090 "pointers unsupported"); 1091 1092 if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) 1093 panic("btaction - Virtual segment " 1094 "addresses unsupported"); 1095 1096 /* Just use the segments provided */ 1097 segs = (struct bus_dma_segment *) 1098 ccb->csio.data_ptr; 1099 ahbexecuteecb(ecb, segs, ccb->csio.sglist_cnt, 1100 0); 1101 } 1102 } else { 1103 ahbexecuteecb(ecb, NULL, 0, 0); 1104 } 1105 break; 1106 } 1107 case XPT_EN_LUN: /* Enable LUN as a target */ 1108 case XPT_TARGET_IO: /* Execute target I/O request */ 1109 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1110 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1111 case XPT_ABORT: /* Abort the specified CCB */ 1112 /* XXX Implement */ 1113 ccb->ccb_h.status = CAM_REQ_INVALID; 1114 xpt_done(ccb); 1115 break; 1116 case XPT_SET_TRAN_SETTINGS: 1117 { 1118 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1119 xpt_done(ccb); 1120 break; 1121 } 1122 case XPT_GET_TRAN_SETTINGS: 1123 /* Get default/user set transfer settings for the target */ 1124 { 1125 struct ccb_trans_settings *cts; 1126 u_int target_mask; 1127 1128 cts = &ccb->cts; 1129 target_mask = 0x01 << ccb->ccb_h.target_id; 1130 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1131 cts->flags = 0; 1132 if ((ahb->disc_permitted & target_mask) != 0) 1133 cts->flags |= CCB_TRANS_DISC_ENB; 1134 if ((ahb->tags_permitted & target_mask) != 0) 1135 cts->flags |= CCB_TRANS_TAG_ENB; 1136 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1137 cts->sync_period = 25; /* 10MHz */ 1138 1139 if (cts->sync_period != 0) 1140 cts->sync_offset = 15; 1141 1142 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1143 | CCB_TRANS_SYNC_OFFSET_VALID 1144 | CCB_TRANS_BUS_WIDTH_VALID 1145 | CCB_TRANS_DISC_VALID 1146 | CCB_TRANS_TQ_VALID; 1147 ccb->ccb_h.status = CAM_REQ_CMP; 1148 } else { 1149 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1150 } 1151 xpt_done(ccb); 1152 break; 1153 } 1154 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 1155 { 1156 int i; 1157 int s; 1158 1159 s = splcam(); 1160 ahb->immed_cmd = IMMED_RESET; 1161 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); 1162 /* Poll for interrupt completion */ 1163 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) { 1164 DELAY(1000); 1165 ahbintr(cam_sim_softc(sim)); 1166 } 1167 splx(s); 1168 break; 1169 } 1170 case XPT_CALC_GEOMETRY: 1171 { 1172 struct ccb_calc_geometry *ccg; 1173 u_int32_t size_mb; 1174 u_int32_t secs_per_cylinder; 1175 1176 ccg = &ccb->ccg; 1177 size_mb = ccg->volume_size 1178 / ((1024L * 1024L) / ccg->block_size); 1179 1180 if (size_mb > 1024 && (ahb->extended_trans != 0)) { 1181 ccg->heads = 255; 1182 ccg->secs_per_track = 63; 1183 } else { 1184 ccg->heads = 64; 1185 ccg->secs_per_track = 32; 1186 } 1187 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1188 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1189 ccb->ccb_h.status = CAM_REQ_CMP; 1190 xpt_done(ccb); 1191 break; 1192 } 1193 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1194 { 1195 int i; 1196 1197 ahb->immed_cmd = IMMED_RESET; 1198 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); 1199 /* Poll for interrupt completion */ 1200 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) 1201 DELAY(1000); 1202 ccb->ccb_h.status = CAM_REQ_CMP; 1203 xpt_done(ccb); 1204 break; 1205 } 1206 case XPT_TERM_IO: /* Terminate the I/O process */ 1207 /* XXX Implement */ 1208 ccb->ccb_h.status = CAM_REQ_INVALID; 1209 xpt_done(ccb); 1210 break; 1211 case XPT_PATH_INQ: /* Path routing inquiry */ 1212 { 1213 struct ccb_pathinq *cpi = &ccb->cpi; 1214 1215 cpi->version_num = 1; /* XXX??? */ 1216 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 1217 cpi->target_sprt = 0; 1218 cpi->hba_misc = 0; 1219 cpi->hba_eng_cnt = 0; 1220 cpi->max_target = 7; 1221 cpi->max_lun = 7; 1222 cpi->initiator_id = ahb->scsi_id; 1223 cpi->bus_id = cam_sim_bus(sim); 1224 cpi->base_transfer_speed = 3300; 1225 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1226 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 1227 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1228 cpi->unit_number = cam_sim_unit(sim); 1229 cpi->ccb_h.status = CAM_REQ_CMP; 1230 xpt_done(ccb); 1231 break; 1232 } 1233#if 0 1234 /* Need these??? */ 1235 case XPT_IMMED_NOTIFY: /* Notify Host Target driver of event */ 1236 case XPT_NOTIFY_ACK: /* Acknowledgement of event */ 1237#endif 1238 default: 1239 ccb->ccb_h.status = CAM_REQ_INVALID; 1240 xpt_done(ccb); 1241 break; 1242 } 1243} 1244 1245static void 1246ahbpoll(struct cam_sim *sim) 1247{ 1248 ahbintr(cam_sim_softc(sim)); 1249} 1250 1251static void 1252ahbtimeout(void *arg) 1253{ 1254 struct ecb *ecb; 1255 union ccb *ccb; 1256 struct ahb_softc *ahb; 1257 int s; 1258 1259 ecb = (struct ecb *)arg; 1260 ccb = ecb->ccb; 1261 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; 1262 xpt_print_path(ccb->ccb_h.path); 1263 printf("ECB %p - timed out\n", (void *)ecb); 1264 1265 s = splcam(); 1266 1267 if ((ecb->state & ECB_ACTIVE) == 0) { 1268 xpt_print_path(ccb->ccb_h.path); 1269 printf("ECB %p - timed out ECB already completed\n", 1270 (void *)ecb); 1271 splx(s); 1272 return; 1273 } 1274 /* 1275 * In order to simplify the recovery process, we ask the XPT 1276 * layer to halt the queue of new transactions and we traverse 1277 * the list of pending CCBs and remove their timeouts. This 1278 * means that the driver attempts to clear only one error 1279 * condition at a time. In general, timeouts that occur 1280 * close together are related anyway, so there is no benefit 1281 * in attempting to handle errors in parrallel. Timeouts will 1282 * be reinstated when the recovery process ends. 1283 */ 1284 if ((ecb->state & ECB_DEVICE_RESET) == 0) { 1285 struct ccb_hdr *ccb_h; 1286 1287 if ((ecb->state & ECB_RELEASE_SIMQ) == 0) { 1288 xpt_freeze_simq(ahb->sim, /*count*/1); 1289 ecb->state |= ECB_RELEASE_SIMQ; 1290 } 1291 1292 ccb_h = LIST_FIRST(&ahb->pending_ccbs); 1293 while (ccb_h != NULL) { 1294 struct ecb *pending_ecb; 1295 1296 pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; 1297 untimeout(ahbtimeout, pending_ecb, ccb_h->timeout_ch); 1298 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1299 } 1300 1301 /* Store for our interrupt handler */ 1302 ahb->immed_ecb = ecb; 1303 1304 /* 1305 * Send a Bus Device Reset message: 1306 * The target that is holding up the bus may not 1307 * be the same as the one that triggered this timeout 1308 * (different commands have different timeout lengths), 1309 * but we have no way of determining this from our 1310 * timeout handler. Our strategy here is to queue a 1311 * BDR message to the target of the timed out command. 1312 * If this fails, we'll get another timeout 2 seconds 1313 * later which will attempt a bus reset. 1314 */ 1315 xpt_print_path(ccb->ccb_h.path); 1316 printf("Queuing BDR\n"); 1317 ecb->state |= ECB_DEVICE_RESET; 1318 ccb->ccb_h.timeout_ch = 1319 timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); 1320 1321 ahb->immed_cmd = IMMED_RESET; 1322 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); 1323 } else if ((ecb->state & ECB_SCSIBUS_RESET) != 0) { 1324 /* 1325 * Try a SCSI bus reset. We do this only if we 1326 * have already attempted to clear the condition with a BDR. 1327 */ 1328 xpt_print_path(ccb->ccb_h.path); 1329 printf("Attempting SCSI Bus reset\n"); 1330 ecb->state |= ECB_SCSIBUS_RESET; 1331 ccb->ccb_h.timeout_ch = 1332 timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); 1333 ahb->immed_cmd = IMMED_RESET; 1334 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); 1335 } else { 1336 /* Bring out the hammer... */ 1337 ahbreset(ahb); 1338 1339 /* Simulate the reset complete interrupt */ 1340 ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK); 1341 } 1342 1343 splx(s); 1344} 1345 1346static device_method_t ahb_eisa_methods[] = { 1347 /* Device interface */ 1348 DEVMETHOD(device_probe, ahbprobe), 1349 DEVMETHOD(device_attach, ahbattach), 1350 1351 { 0, 0 } 1352}; 1353 1354static driver_t ahb_eisa_driver = { 1355 "ahb", 1356 ahb_eisa_methods, 1357 1, /* unused */ 1358}; 1359 1360static devclass_t ahb_devclass; 1361 1362DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0); 1363 1364#endif /* NEISA */
| 316 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 317 /*highaddr*/BUS_SPACE_MAXADDR, 318 /*filter*/NULL, /*filterarg*/NULL, 319 (AHB_NECB * sizeof(struct ecb)) 320 + sizeof(*ahb->ha_inq_data), 321 /*nsegments*/1, 322 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 323 /*flags*/0, &ahb->ecb_dmat) != 0) 324 goto error_exit; 325 326 ahb->init_level++; 327 328 /* Allocation for our ccbs */ 329 if (bus_dmamem_alloc(ahb->ecb_dmat, (void **)&ahb->ecb_array, 330 BUS_DMA_NOWAIT, &ahb->ecb_dmamap) != 0) 331 goto error_exit; 332 333 ahb->ha_inq_data = (struct ha_inquiry_data *)&ahb->ecb_array[AHB_NECB]; 334 335 ahb->init_level++; 336 337 /* And permanently map them */ 338 bus_dmamap_load(ahb->ecb_dmat, ahb->ecb_dmamap, 339 ahb->ecb_array, AHB_NSEG * sizeof(struct ecb), 340 ahbmapecbs, ahb, /*flags*/0); 341 342 ahb->init_level++; 343 344 /* Allocate the buffer dmamaps for each of our ECBs */ 345 bzero(ahb->ecb_array, (AHB_NECB * sizeof(struct ecb)) 346 + sizeof(*ahb->ha_inq_data)); 347 next_ecb = ahb->ecb_array; 348 while (ahb->num_ecbs < AHB_NECB) { 349 u_int32_t ecb_paddr; 350 351 if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0, 352 &next_ecb->dmamap)) 353 break; 354 ecb_paddr = ahbecbvtop(ahb, next_ecb); 355 next_ecb->hecb.status_ptr = ahbstatuspaddr(ecb_paddr); 356 next_ecb->hecb.sense_ptr = ahbsensepaddr(ecb_paddr); 357 ahb->num_ecbs++; 358 ahbecbfree(ahb, next_ecb); 359 next_ecb++; 360 } 361 362 if (ahb->num_ecbs == 0) 363 goto error_exit; 364 365 ahb->init_level++; 366 367 /* 368 * Now that we know we own the resources we need, register 369 * our bus with the XPT. 370 */ 371 if (ahbxptattach(ahb)) 372 goto error_exit; 373 374 /* Enable our interrupt */ 375 bus_setup_intr(dev, irq, INTR_TYPE_CAM, ahbintr, ahb, &ih); 376 return (0); 377 378error_exit: 379 /* 380 * The board's IRQ line will not be left enabled 381 * if we can't intialize correctly, so its safe 382 * to release the irq. 383 */ 384 ahbfree(ahb); 385error_exit2: 386 if (io) 387 bus_release_resource(dev, SYS_RES_IOPORT, 0, io); 388 if (irq) 389 bus_release_resource(dev, SYS_RES_IRQ, 0, irq); 390 return (-1); 391} 392 393static struct ahb_softc * 394ahballoc(u_long unit, u_int iobase) 395{ 396 struct ahb_softc *ahb; 397 398 /* 399 * Allocate a storage area for us 400 */ 401 ahb = malloc(sizeof(struct ahb_softc), M_DEVBUF, M_NOWAIT); 402 if (!ahb) { 403 printf("ahb%ld: cannot malloc!\n", unit); 404 return (NULL); 405 } 406 bzero(ahb, sizeof(struct ahb_softc)); 407 SLIST_INIT(&ahb->free_ecbs); 408 LIST_INIT(&ahb->pending_ccbs); 409 ahb->unit = unit; 410 ahb->tag = I386_BUS_SPACE_IO; 411 ahb->bsh = iobase; 412 ahb->disc_permitted = ~0; 413 ahb->tags_permitted = ~0; 414 415 return (ahb); 416} 417 418static void 419ahbfree(struct ahb_softc *ahb) 420{ 421 switch (ahb->init_level) { 422 default: 423 case 4: 424 bus_dmamap_unload(ahb->ecb_dmat, ahb->ecb_dmamap); 425 case 3: 426 bus_dmamem_free(ahb->ecb_dmat, ahb->ecb_array, 427 ahb->ecb_dmamap); 428 bus_dmamap_destroy(ahb->ecb_dmat, ahb->ecb_dmamap); 429 case 2: 430 bus_dma_tag_destroy(ahb->ecb_dmat); 431 case 1: 432 bus_dma_tag_destroy(ahb->buffer_dmat); 433 case 0: 434 } 435 free(ahb, M_DEVBUF); 436} 437 438/* 439 * reset board, If it doesn't respond, return failure 440 */ 441static int 442ahbreset(struct ahb_softc *ahb) 443{ 444 int wait = 1000; /* 1 sec enough? */ 445 int test; 446 447 if ((ahb_inb(ahb, PORTADDR) & PORTADDR_ENHANCED) == 0) { 448 printf("ahb_reset: Controller not in enhanced mode\n"); 449 return (-1); 450 } 451 452 ahb_outb(ahb, CONTROL, CNTRL_HARD_RST); 453 DELAY(1000); 454 ahb_outb(ahb, CONTROL, 0); 455 while (--wait) { 456 DELAY(1000); 457 if ((ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_BUSY) == 0) 458 break; 459 } 460 461 if (wait == 0) { 462 printf("ahbreset: No answer from aha1742 board\n"); 463 return (-1); 464 } 465 if ((test = ahb_inb(ahb, MBOXIN0)) != 0) { 466 printf("ahb_reset: self test failed, val = 0x%x\n", test); 467 return (-1); 468 } 469 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { 470 ahb_outb(ahb, CONTROL, CNTRL_CLRINT); 471 DELAY(10000); 472 } 473 return (0); 474} 475 476static void 477ahbmapecbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 478{ 479 struct ahb_softc* ahb; 480 481 ahb = (struct ahb_softc*)arg; 482 ahb->ecb_physbase = segs->ds_addr; 483 /* 484 * Space for adapter inquiry information is on the 485 * tail of the ecb array. 486 */ 487 ahb->ha_inq_physbase = ahbecbvtop(ahb, &ahb->ecb_array[AHB_NECB]); 488} 489 490static int 491ahbxptattach(struct ahb_softc *ahb) 492{ 493 struct cam_devq *devq; 494 struct ecb *ecb; 495 u_int i; 496 497 /* Remeber who are we on the scsi bus */ 498 ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID; 499 500 /* Use extended translation?? */ 501 ahb->extended_trans = ahb_inb(ahb, RESV1) & EXTENDED_TRANS; 502 503 /* Fetch adapter inquiry data */ 504 ecb = ahbecbget(ahb); /* Always succeeds - no outstanding commands */ 505 ecb->hecb.opcode = ECBOP_READ_HA_INQDATA; 506 ecb->hecb.flag_word1 = FW1_SUPPRESS_URUN_ERR|FW1_ERR_STATUS_BLK_ONLY; 507 ecb->hecb.data_ptr = ahb->ha_inq_physbase; 508 ecb->hecb.data_len = sizeof(struct ha_inquiry_data); 509 ecb->hecb.sense_ptr = 0; 510 ecb->state = ECB_ACTIVE; 511 512 /* Tell the adapter about this command */ 513 ahbqueuembox(ahb, ahbecbvtop(ahb, ecb), 514 ATTN_STARTECB|ahb->scsi_id); 515 516 /* Poll for interrupt completion */ 517 for (i = 1000; ecb->state != ECB_FREE && i != 0; i--) { 518 ahbintr(ahb); 519 DELAY(1000); 520 } 521 522 ahb->num_ecbs = MIN(ahb->num_ecbs, 523 ahb->ha_inq_data->scsi_data.reserved[1]); 524 printf("ahb%ld: %.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n", 525 ahb->unit, ahb->ha_inq_data->scsi_data.product, 526 (ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential" 527 : "Single Ended", 528 ahb->ha_inq_data->scsi_data.revision, 529 ahb->scsi_id, ahb->num_ecbs); 530 531 /* Restore sense paddr for future CCB clients */ 532 ecb->hecb.sense_ptr = ahbsensepaddr(ahbecbvtop(ahb, ecb)); 533 534 ahbecbfree(ahb, ecb); 535 536 /* 537 * Create the device queue for our SIM. 538 */ 539 devq = cam_simq_alloc(ahb->num_ecbs); 540 if (devq == NULL) 541 return (ENOMEM); 542 543 /* 544 * Construct our SIM entry 545 */ 546 ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb, ahb->unit, 547 2, ahb->num_ecbs, devq); 548 if (ahb->sim == NULL) { 549 cam_simq_free(devq); 550 return (ENOMEM); 551 } 552 553 if (xpt_bus_register(ahb->sim, 0) != CAM_SUCCESS) { 554 cam_sim_free(ahb->sim, /*free_devq*/TRUE); 555 return (ENXIO); 556 } 557 558 if (xpt_create_path(&ahb->path, /*periph*/NULL, 559 cam_sim_path(ahb->sim), CAM_TARGET_WILDCARD, 560 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 561 xpt_bus_deregister(cam_sim_path(ahb->sim)); 562 cam_sim_free(ahb->sim, /*free_devq*/TRUE); 563 return (ENXIO); 564 } 565 566 /* 567 * Allow the board to generate interrupts. 568 */ 569 ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN); 570 571 return (0); 572} 573 574static void 575ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) 576{ 577 struct ccb_hdr *ccb_h; 578 u_int target_id; 579 580 if (ahb->immed_cmd == 0) { 581 printf("ahb%ld: Immediate Command complete with no " 582 " pending command\n", ahb->unit); 583 return; 584 } 585 586 target_id = intstat & INTSTAT_TARGET_MASK; 587 588 ccb_h = LIST_FIRST(&ahb->pending_ccbs); 589 while (ccb_h != NULL) { 590 struct ecb *pending_ecb; 591 union ccb *ccb; 592 593 pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; 594 ccb = pending_ecb->ccb; 595 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 596 if (ccb->ccb_h.target_id == target_id 597 || target_id == ahb->scsi_id) { 598 untimeout(ahbtimeout, pending_ecb, 599 ccb->ccb_h.timeout_ch); 600 LIST_REMOVE(&ccb->ccb_h, sim_links.le); 601 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) 602 bus_dmamap_unload(ahb->buffer_dmat, 603 pending_ecb->dmamap); 604 if (pending_ecb == ahb->immed_ecb) 605 ccb->ccb_h.status = 606 CAM_CMD_TIMEOUT|CAM_RELEASE_SIMQ; 607 else if (target_id == ahb->scsi_id) 608 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 609 else 610 ccb->ccb_h.status = CAM_BDR_SENT; 611 ahbecbfree(ahb, pending_ecb); 612 xpt_done(ccb); 613 } else if (ahb->immed_ecb != NULL) { 614 /* Re-instate timeout */ 615 ccb->ccb_h.timeout_ch = 616 timeout(ahbtimeout, (caddr_t)pending_ecb, 617 (ccb->ccb_h.timeout * hz) / 1000); 618 } 619 } 620 621 if (ahb->immed_ecb != NULL) { 622 ahb->immed_ecb = NULL; 623 printf("ahb%ld: No longer in timeout\n", ahb->unit); 624 } else if (target_id == ahb->scsi_id) 625 printf("ahb%ld: SCSI Bus Reset Delivered\n", ahb->unit); 626 else 627 printf("ahb%ld: Bus Device Reset Delibered to target %d\n", 628 ahb->unit, target_id); 629 630 ahb->immed_cmd = 0; 631} 632 633static void 634ahbcalcresid(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) 635{ 636 if (ecb->status.data_overrun != 0) { 637 /* 638 * Overrun Condition. The hardware doesn't 639 * provide a meaningful byte count in this case 640 * (the residual is always 0). Tell the XPT 641 * layer about the error. 642 */ 643 ccb->ccb_h.status = CAM_DATA_RUN_ERR; 644 } else { 645 ccb->csio.resid = ecb->status.resid_count; 646 647 if ((ecb->hecb.flag_word1 & FW1_SG_ECB) != 0) { 648 /* 649 * For S/G transfers, the adapter provides a pointer 650 * to the address in the last S/G element used and a 651 * residual for that element. So, we need to sum up 652 * the elements that follow it in order to get a real 653 * residual number. If we have an overrun, the residual 654 * reported will be 0 and we already know that all S/G 655 * segments have been exhausted, so we can skip this 656 * step. 657 */ 658 ahb_sg_t *sg; 659 int num_sg; 660 661 num_sg = ecb->hecb.data_len / sizeof(ahb_sg_t); 662 663 /* Find the S/G the adapter was working on */ 664 for (sg = ecb->sg_list; 665 num_sg != 0 && sg->addr != ecb->status.resid_addr; 666 num_sg--, sg++) 667 ; 668 669 /* Skip it */ 670 num_sg--; 671 sg++; 672 673 /* Sum the rest */ 674 for (; num_sg != 0; num_sg--, sg++) 675 ccb->csio.resid += sg->len; 676 } 677 /* Underruns are not errors */ 678 ccb->ccb_h.status = CAM_REQ_CMP; 679 } 680} 681 682static void 683ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) 684{ 685 struct hardware_ecb *hecb; 686 struct ecb_status *status; 687 688 hecb = &ecb->hecb; 689 status = &ecb->status; 690 switch (status->ha_status) { 691 case HS_OK: 692 ccb->csio.scsi_status = status->scsi_status; 693 if (status->scsi_status != 0) { 694 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 695 if (status->sense_stored) { 696 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 697 ccb->csio.sense_resid = 698 ccb->csio.sense_len - status->sense_len; 699 bcopy(&ecb->sense, &ccb->csio.sense_data, 700 status->sense_len); 701 } 702 } 703 break; 704 case HS_TARGET_NOT_ASSIGNED: 705 ccb->ccb_h.status = CAM_PATH_INVALID; 706 break; 707 case HS_SEL_TIMEOUT: 708 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 709 break; 710 case HS_DATA_RUN_ERR: 711 ahbcalcresid(ahb, ecb, ccb); 712 break; 713 case HS_UNEXPECTED_BUSFREE: 714 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 715 break; 716 case HS_INVALID_PHASE: 717 ccb->ccb_h.status = CAM_SEQUENCE_FAIL; 718 break; 719 case HS_REQUEST_SENSE_FAILED: 720 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; 721 break; 722 case HS_TAG_MSG_REJECTED: 723 { 724 struct ccb_trans_settings neg; 725 726 xpt_print_path(ccb->ccb_h.path); 727 printf("refuses tagged commands. Performing " 728 "non-tagged I/O\n"); 729 neg.flags = 0; 730 neg.valid = CCB_TRANS_TQ_VALID; 731 xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); 732 xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); 733 ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id); 734 ccb->ccb_h.status = CAM_MSG_REJECT_REC; 735 break; 736 } 737 case HS_FIRMWARE_LOAD_REQ: 738 case HS_HARDWARE_ERR: 739 /* 740 * Tell the system that the Adapter 741 * is no longer functional. 742 */ 743 ccb->ccb_h.status = CAM_NO_HBA; 744 break; 745 case HS_CMD_ABORTED_HOST: 746 case HS_CMD_ABORTED_ADAPTER: 747 case HS_ATN_TARGET_FAILED: 748 case HS_SCSI_RESET_ADAPTER: 749 case HS_SCSI_RESET_INCOMING: 750 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 751 break; 752 case HS_INVALID_ECB_PARAM: 753 printf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n", 754 ahb->unit, hecb->opcode, hecb->flag_word1, hecb->flag_word2); 755 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 756 break; 757 case HS_DUP_TCB_RECEIVED: 758 case HS_INVALID_OPCODE: 759 case HS_INVALID_CMD_LINK: 760 case HS_PROGRAM_CKSUM_ERROR: 761 panic("ahb%ld: Can't happen host status %x occurred", 762 ahb->unit, status->ha_status); 763 break; 764 } 765 if (ccb->ccb_h.status != CAM_REQ_CMP) { 766 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 767 ccb->ccb_h.status |= CAM_DEV_QFRZN; 768 } 769} 770 771static void 772ahbdone(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) 773{ 774 struct ecb *ecb; 775 union ccb *ccb; 776 777 ecb = ahbecbptov(ahb, mbox); 778 779 if ((ecb->state & ECB_ACTIVE) == 0) 780 panic("ecb not active"); 781 782 ccb = ecb->ccb; 783 784 if (ccb != NULL) { 785 untimeout(ahbtimeout, ecb, ccb->ccb_h.timeout_ch); 786 LIST_REMOVE(&ccb->ccb_h, sim_links.le); 787 788 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 789 bus_dmasync_op_t op; 790 791 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 792 op = BUS_DMASYNC_POSTREAD; 793 else 794 op = BUS_DMASYNC_POSTWRITE; 795 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); 796 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); 797 } 798 799 if ((intstat & INTSTAT_MASK) == INTSTAT_ECB_OK) { 800 ccb->ccb_h.status = CAM_REQ_CMP; 801 ccb->csio.resid = 0; 802 } else { 803 ahbprocesserror(ahb, ecb, ccb); 804 } 805 ahbecbfree(ahb, ecb); 806 xpt_done(ccb); 807 } else { 808 /* Non CCB Command */ 809 if ((intstat & INTSTAT_MASK) != INTSTAT_ECB_OK) { 810 printf("ahb%ld: Command 0%x Failed %x:%x:%x\n", 811 ahb->unit, ecb->hecb.opcode, 812 *((u_int16_t*)&ecb->status), 813 ecb->status.ha_status, ecb->status.resid_count); 814 } 815 /* Client owns this ECB and will release it. */ 816 } 817} 818 819/* 820 * Catch an interrupt from the adaptor 821 */ 822static void 823ahbintr(void *arg) 824{ 825 struct ahb_softc *ahb; 826 u_int intstat; 827 u_int32_t mbox; 828 829 ahb = (struct ahb_softc *)arg; 830 831 while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { 832 /* 833 * Fetch information about this interrupt. 834 */ 835 intstat = ahb_inb(ahb, INTSTAT); 836 mbox = ahb_inl(ahb, MBOXIN0); 837 838 /* 839 * Reset interrupt latch. 840 */ 841 ahb_outb(ahb, CONTROL, CNTRL_CLRINT); 842 843 /* 844 * Process the completed operation 845 */ 846 switch (intstat & INTSTAT_MASK) { 847 case INTSTAT_ECB_OK: 848 case INTSTAT_ECB_CMPWRETRY: 849 case INTSTAT_ECB_CMPWERR: 850 ahbdone(ahb, mbox, intstat); 851 break; 852 case INTSTAT_AEN_OCCURED: 853 if ((intstat & INTSTAT_TARGET_MASK) == ahb->scsi_id) { 854 /* Bus Reset */ 855 xpt_print_path(ahb->path); 856 switch (mbox) { 857 case HS_SCSI_RESET_ADAPTER: 858 printf("Host Adapter Initiated " 859 "Bus Reset occurred\n"); 860 break; 861 case HS_SCSI_RESET_INCOMING: 862 printf("Bus Reset Initiated " 863 "by another device occurred\n"); 864 break; 865 } 866 /* Notify the XPT */ 867 xpt_async(AC_BUS_RESET, ahb->path, NULL); 868 break; 869 } 870 printf("Unsupported initiator selection AEN occured\n"); 871 break; 872 case INTSTAT_IMMED_OK: 873 case INTSTAT_IMMED_ERR: 874 ahbhandleimmed(ahb, mbox, intstat); 875 break; 876 case INTSTAT_HW_ERR: 877 panic("Unrecoverable hardware Error Occurred\n"); 878 } 879 } 880} 881 882static void 883ahbexecuteecb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 884{ 885 struct ecb *ecb; 886 union ccb *ccb; 887 struct ahb_softc *ahb; 888 u_int32_t ecb_paddr; 889 int s; 890 891 ecb = (struct ecb *)arg; 892 ccb = ecb->ccb; 893 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; 894 895 if (error != 0) { 896 if (error != EFBIG) 897 printf("ahb%ld: Unexepected error 0x%x returned from " 898 "bus_dmamap_load\n", ahb->unit, error); 899 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 900 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 901 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 902 } 903 ahbecbfree(ahb, ecb); 904 xpt_done(ccb); 905 return; 906 } 907 908 ecb_paddr = ahbecbvtop(ahb, ecb); 909 910 if (nseg != 0) { 911 ahb_sg_t *sg; 912 bus_dma_segment_t *end_seg; 913 bus_dmasync_op_t op; 914 915 end_seg = dm_segs + nseg; 916 917 /* Copy the segments into our SG list */ 918 sg = ecb->sg_list; 919 while (dm_segs < end_seg) { 920 sg->addr = dm_segs->ds_addr; 921 sg->len = dm_segs->ds_len; 922 sg++; 923 dm_segs++; 924 } 925 926 if (nseg > 1) { 927 ecb->hecb.flag_word1 |= FW1_SG_ECB; 928 ecb->hecb.data_ptr = ahbsgpaddr(ecb_paddr); 929 ecb->hecb.data_len = sizeof(ahb_sg_t) * nseg; 930 } else { 931 ecb->hecb.data_ptr = ecb->sg_list->addr; 932 ecb->hecb.data_len = ecb->sg_list->len; 933 } 934 935 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 936/* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */ 937 op = BUS_DMASYNC_PREREAD; 938 } else { 939 op = BUS_DMASYNC_PREWRITE; 940 } 941 /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */ 942 943 bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); 944 945 } else { 946 ecb->hecb.data_ptr = 0; 947 ecb->hecb.data_len = 0; 948 } 949 950 s = splcam(); 951 952 /* 953 * Last time we need to check if this CCB needs to 954 * be aborted. 955 */ 956 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 957 if (nseg != 0) 958 bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); 959 ahbecbfree(ahb, ecb); 960 xpt_done(ccb); 961 splx(s); 962 return; 963 } 964 965 ecb->state = ECB_ACTIVE; 966 ccb->ccb_h.status |= CAM_SIM_QUEUED; 967 LIST_INSERT_HEAD(&ahb->pending_ccbs, &ccb->ccb_h, sim_links.le); 968 969 /* Tell the adapter about this command */ 970 ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id); 971 972 ccb->ccb_h.timeout_ch = timeout(ahbtimeout, (caddr_t)ecb, 973 (ccb->ccb_h.timeout * hz) / 1000); 974 splx(s); 975} 976 977static void 978ahbaction(struct cam_sim *sim, union ccb *ccb) 979{ 980 struct ahb_softc *ahb; 981 982 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahbaction\n")); 983 984 ahb = (struct ahb_softc *)cam_sim_softc(sim); 985 986 switch (ccb->ccb_h.func_code) { 987 /* Common cases first */ 988 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 989 { 990 struct ecb *ecb; 991 struct hardware_ecb *hecb; 992 993 /* 994 * get an ecb to use. 995 */ 996 if ((ecb = ahbecbget(ahb)) == NULL) { 997 /* Should never occur */ 998 panic("Failed to get an ecb"); 999 } 1000 1001 /* 1002 * So we can find the ECB when an abort is requested 1003 */ 1004 ecb->ccb = ccb; 1005 ccb->ccb_h.ccb_ecb_ptr = ecb; 1006 ccb->ccb_h.ccb_ahb_ptr = ahb; 1007 1008 /* 1009 * Put all the arguments for the xfer in the ecb 1010 */ 1011 hecb = &ecb->hecb; 1012 hecb->opcode = ECBOP_INITIATOR_SCSI_CMD; 1013 hecb->flag_word1 = FW1_AUTO_REQUEST_SENSE 1014 | FW1_ERR_STATUS_BLK_ONLY; 1015 hecb->flag_word2 = ccb->ccb_h.target_lun 1016 | FW2_NO_RETRY_ON_BUSY; 1017 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { 1018 hecb->flag_word2 |= FW2_TAG_ENB 1019 | ((ccb->csio.tag_action & 0x3) 1020 << FW2_TAG_TYPE_SHIFT); 1021 } 1022 if ((ccb->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) 1023 hecb->flag_word2 |= FW2_DISABLE_DISC; 1024 hecb->sense_len = ccb->csio.sense_len; 1025 hecb->cdb_len = ccb->csio.cdb_len; 1026 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 1027 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { 1028 bcopy(ccb->csio.cdb_io.cdb_ptr, 1029 hecb->cdb, hecb->cdb_len); 1030 } else { 1031 /* I guess I could map it in... */ 1032 ccb->ccb_h.status = CAM_REQ_INVALID; 1033 ahbecbfree(ahb, ecb); 1034 xpt_done(ccb); 1035 return; 1036 } 1037 } else { 1038 bcopy(ccb->csio.cdb_io.cdb_bytes, 1039 hecb->cdb, hecb->cdb_len); 1040 } 1041 1042 /* 1043 * If we have any data to send with this command, 1044 * map it into bus space. 1045 */ 1046 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1047 if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { 1048 /* 1049 * We've been given a pointer 1050 * to a single buffer. 1051 */ 1052 if ((ccb->ccb_h.flags & CAM_DATA_PHYS)==0) { 1053 int s; 1054 int error; 1055 1056 s = splsoftvm(); 1057 error = bus_dmamap_load( 1058 ahb->buffer_dmat, 1059 ecb->dmamap, 1060 ccb->csio.data_ptr, 1061 ccb->csio.dxfer_len, 1062 ahbexecuteecb, 1063 ecb, /*flags*/0); 1064 if (error == EINPROGRESS) { 1065 /* 1066 * So as to maintain ordering, 1067 * freeze the controller queue 1068 * until our mapping is 1069 * returned. 1070 */ 1071 xpt_freeze_simq(ahb->sim, 1); 1072 ccb->ccb_h.status |= 1073 CAM_RELEASE_SIMQ; 1074 } 1075 splx(s); 1076 } else { 1077 struct bus_dma_segment seg; 1078 1079 /* Pointer to physical buffer */ 1080 seg.ds_addr = 1081 (bus_addr_t)ccb->csio.data_ptr; 1082 seg.ds_len = ccb->csio.dxfer_len; 1083 ahbexecuteecb(ecb, &seg, 1, 0); 1084 } 1085 } else { 1086 struct bus_dma_segment *segs; 1087 1088 if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) 1089 panic("ahbaction - Physical segment " 1090 "pointers unsupported"); 1091 1092 if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) 1093 panic("btaction - Virtual segment " 1094 "addresses unsupported"); 1095 1096 /* Just use the segments provided */ 1097 segs = (struct bus_dma_segment *) 1098 ccb->csio.data_ptr; 1099 ahbexecuteecb(ecb, segs, ccb->csio.sglist_cnt, 1100 0); 1101 } 1102 } else { 1103 ahbexecuteecb(ecb, NULL, 0, 0); 1104 } 1105 break; 1106 } 1107 case XPT_EN_LUN: /* Enable LUN as a target */ 1108 case XPT_TARGET_IO: /* Execute target I/O request */ 1109 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1110 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1111 case XPT_ABORT: /* Abort the specified CCB */ 1112 /* XXX Implement */ 1113 ccb->ccb_h.status = CAM_REQ_INVALID; 1114 xpt_done(ccb); 1115 break; 1116 case XPT_SET_TRAN_SETTINGS: 1117 { 1118 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1119 xpt_done(ccb); 1120 break; 1121 } 1122 case XPT_GET_TRAN_SETTINGS: 1123 /* Get default/user set transfer settings for the target */ 1124 { 1125 struct ccb_trans_settings *cts; 1126 u_int target_mask; 1127 1128 cts = &ccb->cts; 1129 target_mask = 0x01 << ccb->ccb_h.target_id; 1130 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1131 cts->flags = 0; 1132 if ((ahb->disc_permitted & target_mask) != 0) 1133 cts->flags |= CCB_TRANS_DISC_ENB; 1134 if ((ahb->tags_permitted & target_mask) != 0) 1135 cts->flags |= CCB_TRANS_TAG_ENB; 1136 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1137 cts->sync_period = 25; /* 10MHz */ 1138 1139 if (cts->sync_period != 0) 1140 cts->sync_offset = 15; 1141 1142 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1143 | CCB_TRANS_SYNC_OFFSET_VALID 1144 | CCB_TRANS_BUS_WIDTH_VALID 1145 | CCB_TRANS_DISC_VALID 1146 | CCB_TRANS_TQ_VALID; 1147 ccb->ccb_h.status = CAM_REQ_CMP; 1148 } else { 1149 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1150 } 1151 xpt_done(ccb); 1152 break; 1153 } 1154 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 1155 { 1156 int i; 1157 int s; 1158 1159 s = splcam(); 1160 ahb->immed_cmd = IMMED_RESET; 1161 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); 1162 /* Poll for interrupt completion */ 1163 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) { 1164 DELAY(1000); 1165 ahbintr(cam_sim_softc(sim)); 1166 } 1167 splx(s); 1168 break; 1169 } 1170 case XPT_CALC_GEOMETRY: 1171 { 1172 struct ccb_calc_geometry *ccg; 1173 u_int32_t size_mb; 1174 u_int32_t secs_per_cylinder; 1175 1176 ccg = &ccb->ccg; 1177 size_mb = ccg->volume_size 1178 / ((1024L * 1024L) / ccg->block_size); 1179 1180 if (size_mb > 1024 && (ahb->extended_trans != 0)) { 1181 ccg->heads = 255; 1182 ccg->secs_per_track = 63; 1183 } else { 1184 ccg->heads = 64; 1185 ccg->secs_per_track = 32; 1186 } 1187 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1188 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1189 ccb->ccb_h.status = CAM_REQ_CMP; 1190 xpt_done(ccb); 1191 break; 1192 } 1193 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1194 { 1195 int i; 1196 1197 ahb->immed_cmd = IMMED_RESET; 1198 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); 1199 /* Poll for interrupt completion */ 1200 for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) 1201 DELAY(1000); 1202 ccb->ccb_h.status = CAM_REQ_CMP; 1203 xpt_done(ccb); 1204 break; 1205 } 1206 case XPT_TERM_IO: /* Terminate the I/O process */ 1207 /* XXX Implement */ 1208 ccb->ccb_h.status = CAM_REQ_INVALID; 1209 xpt_done(ccb); 1210 break; 1211 case XPT_PATH_INQ: /* Path routing inquiry */ 1212 { 1213 struct ccb_pathinq *cpi = &ccb->cpi; 1214 1215 cpi->version_num = 1; /* XXX??? */ 1216 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 1217 cpi->target_sprt = 0; 1218 cpi->hba_misc = 0; 1219 cpi->hba_eng_cnt = 0; 1220 cpi->max_target = 7; 1221 cpi->max_lun = 7; 1222 cpi->initiator_id = ahb->scsi_id; 1223 cpi->bus_id = cam_sim_bus(sim); 1224 cpi->base_transfer_speed = 3300; 1225 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1226 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); 1227 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1228 cpi->unit_number = cam_sim_unit(sim); 1229 cpi->ccb_h.status = CAM_REQ_CMP; 1230 xpt_done(ccb); 1231 break; 1232 } 1233#if 0 1234 /* Need these??? */ 1235 case XPT_IMMED_NOTIFY: /* Notify Host Target driver of event */ 1236 case XPT_NOTIFY_ACK: /* Acknowledgement of event */ 1237#endif 1238 default: 1239 ccb->ccb_h.status = CAM_REQ_INVALID; 1240 xpt_done(ccb); 1241 break; 1242 } 1243} 1244 1245static void 1246ahbpoll(struct cam_sim *sim) 1247{ 1248 ahbintr(cam_sim_softc(sim)); 1249} 1250 1251static void 1252ahbtimeout(void *arg) 1253{ 1254 struct ecb *ecb; 1255 union ccb *ccb; 1256 struct ahb_softc *ahb; 1257 int s; 1258 1259 ecb = (struct ecb *)arg; 1260 ccb = ecb->ccb; 1261 ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; 1262 xpt_print_path(ccb->ccb_h.path); 1263 printf("ECB %p - timed out\n", (void *)ecb); 1264 1265 s = splcam(); 1266 1267 if ((ecb->state & ECB_ACTIVE) == 0) { 1268 xpt_print_path(ccb->ccb_h.path); 1269 printf("ECB %p - timed out ECB already completed\n", 1270 (void *)ecb); 1271 splx(s); 1272 return; 1273 } 1274 /* 1275 * In order to simplify the recovery process, we ask the XPT 1276 * layer to halt the queue of new transactions and we traverse 1277 * the list of pending CCBs and remove their timeouts. This 1278 * means that the driver attempts to clear only one error 1279 * condition at a time. In general, timeouts that occur 1280 * close together are related anyway, so there is no benefit 1281 * in attempting to handle errors in parrallel. Timeouts will 1282 * be reinstated when the recovery process ends. 1283 */ 1284 if ((ecb->state & ECB_DEVICE_RESET) == 0) { 1285 struct ccb_hdr *ccb_h; 1286 1287 if ((ecb->state & ECB_RELEASE_SIMQ) == 0) { 1288 xpt_freeze_simq(ahb->sim, /*count*/1); 1289 ecb->state |= ECB_RELEASE_SIMQ; 1290 } 1291 1292 ccb_h = LIST_FIRST(&ahb->pending_ccbs); 1293 while (ccb_h != NULL) { 1294 struct ecb *pending_ecb; 1295 1296 pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; 1297 untimeout(ahbtimeout, pending_ecb, ccb_h->timeout_ch); 1298 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1299 } 1300 1301 /* Store for our interrupt handler */ 1302 ahb->immed_ecb = ecb; 1303 1304 /* 1305 * Send a Bus Device Reset message: 1306 * The target that is holding up the bus may not 1307 * be the same as the one that triggered this timeout 1308 * (different commands have different timeout lengths), 1309 * but we have no way of determining this from our 1310 * timeout handler. Our strategy here is to queue a 1311 * BDR message to the target of the timed out command. 1312 * If this fails, we'll get another timeout 2 seconds 1313 * later which will attempt a bus reset. 1314 */ 1315 xpt_print_path(ccb->ccb_h.path); 1316 printf("Queuing BDR\n"); 1317 ecb->state |= ECB_DEVICE_RESET; 1318 ccb->ccb_h.timeout_ch = 1319 timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); 1320 1321 ahb->immed_cmd = IMMED_RESET; 1322 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); 1323 } else if ((ecb->state & ECB_SCSIBUS_RESET) != 0) { 1324 /* 1325 * Try a SCSI bus reset. We do this only if we 1326 * have already attempted to clear the condition with a BDR. 1327 */ 1328 xpt_print_path(ccb->ccb_h.path); 1329 printf("Attempting SCSI Bus reset\n"); 1330 ecb->state |= ECB_SCSIBUS_RESET; 1331 ccb->ccb_h.timeout_ch = 1332 timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); 1333 ahb->immed_cmd = IMMED_RESET; 1334 ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); 1335 } else { 1336 /* Bring out the hammer... */ 1337 ahbreset(ahb); 1338 1339 /* Simulate the reset complete interrupt */ 1340 ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK); 1341 } 1342 1343 splx(s); 1344} 1345 1346static device_method_t ahb_eisa_methods[] = { 1347 /* Device interface */ 1348 DEVMETHOD(device_probe, ahbprobe), 1349 DEVMETHOD(device_attach, ahbattach), 1350 1351 { 0, 0 } 1352}; 1353 1354static driver_t ahb_eisa_driver = { 1355 "ahb", 1356 ahb_eisa_methods, 1357 1, /* unused */ 1358}; 1359 1360static devclass_t ahb_devclass; 1361 1362DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0); 1363 1364#endif /* NEISA */
|