1/* 2 * Generic driver for the BusLogic MultiMaster SCSI host adapters 3 * Product specific probe and attach routines can be found in: 4 * i386/isa/bt_isa.c BT-54X, BT-445 cards 5 * i386/eisa/bt_eisa.c BT-74x, BT-75x cards 6 * pci/bt_pci.c BT-946, BT-948, BT-956, BT-958 cards 7 * 8 * Copyright (c) 1998 Justin T. Gibbs. 9 * All rights reserved. 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 * without modification, immediately at the beginning of the file. 17 * 2. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 *
| 1/* 2 * Generic driver for the BusLogic MultiMaster SCSI host adapters 3 * Product specific probe and attach routines can be found in: 4 * i386/isa/bt_isa.c BT-54X, BT-445 cards 5 * i386/eisa/bt_eisa.c BT-74x, BT-75x cards 6 * pci/bt_pci.c BT-946, BT-948, BT-956, BT-958 cards 7 * 8 * Copyright (c) 1998 Justin T. Gibbs. 9 * All rights reserved. 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 * without modification, immediately at the beginning of the file. 17 * 2. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 *
|
32 * $Id: bt.c,v 1.7 1998/10/15 23:46:28 gibbs Exp $
| 32 * $Id: bt.c,v 1.8 1998/10/30 02:06:44 gibbs Exp $
|
33 */ 34 35 /* 36 * Special thanks to Leonard N. Zubkoff for writing such a complete and 37 * well documented Mylex/BusLogic MultiMaster driver for Linux. Support 38 * in this driver for the wide range of MultiMaster controllers and 39 * firmware revisions, with their otherwise undocumented quirks, would not 40 * have been possible without his efforts. 41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/malloc.h> 46#include <sys/buf.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49 50/* 51 * XXX It appears that BusLogic PCI adapters go out to lunch if you 52 * attempt to perform memory mapped I/O. 53 */ 54#if 0 55#include "pci.h" 56#if NPCI > 0 57#include <machine/bus_memio.h> 58#endif 59#endif 60#include <machine/bus_pio.h> 61#include <machine/bus.h> 62#include <machine/clock.h> 63 64#include <cam/cam.h> 65#include <cam/cam_ccb.h> 66#include <cam/cam_sim.h> 67#include <cam/cam_xpt_sim.h> 68#include <cam/cam_debug.h> 69 70#include <cam/scsi/scsi_message.h> 71 72#include <vm/vm.h> 73#include <vm/pmap.h> 74 75#include <dev/buslogic/btreg.h> 76 77struct bt_softc *bt_softcs[NBT]; 78 79/* MailBox Management functions */ 80static __inline void btnextinbox(struct bt_softc *bt); 81static __inline void btnextoutbox(struct bt_softc *bt); 82 83static __inline void 84btnextinbox(struct bt_softc *bt) 85{ 86 if (bt->cur_inbox == bt->last_inbox) 87 bt->cur_inbox = bt->in_boxes; 88 else 89 bt->cur_inbox++; 90} 91 92static __inline void 93btnextoutbox(struct bt_softc *bt) 94{ 95 if (bt->cur_outbox == bt->last_outbox) 96 bt->cur_outbox = bt->out_boxes; 97 else 98 bt->cur_outbox++; 99} 100 101/* CCB Mangement functions */ 102static __inline u_int32_t btccbvtop(struct bt_softc *bt, 103 struct bt_ccb *bccb); 104static __inline struct bt_ccb* btccbptov(struct bt_softc *bt, 105 u_int32_t ccb_addr); 106static __inline u_int32_t btsensepaddr(struct bt_softc *bt, 107 struct bt_ccb *bccb); 108static __inline struct scsi_sense_data* btsensevaddr(struct bt_softc *bt, 109 struct bt_ccb *bccb); 110 111static __inline u_int32_t 112btccbvtop(struct bt_softc *bt, struct bt_ccb *bccb) 113{ 114 return (bt->bt_ccb_physbase 115 + (u_int32_t)((caddr_t)bccb - (caddr_t)bt->bt_ccb_array)); 116} 117 118static __inline struct bt_ccb * 119btccbptov(struct bt_softc *bt, u_int32_t ccb_addr) 120{ 121 return (bt->bt_ccb_array + 122 ((struct bt_ccb*)ccb_addr-(struct bt_ccb*)bt->bt_ccb_physbase)); 123} 124 125static __inline u_int32_t 126btsensepaddr(struct bt_softc *bt, struct bt_ccb *bccb) 127{ 128 u_int index; 129 130 index = (u_int)(bccb - bt->bt_ccb_array); 131 return (bt->sense_buffers_physbase 132 + (index * sizeof(struct scsi_sense_data))); 133} 134 135static __inline struct scsi_sense_data * 136btsensevaddr(struct bt_softc *bt, struct bt_ccb *bccb) 137{ 138 u_int index; 139 140 index = (u_int)(bccb - bt->bt_ccb_array); 141 return (bt->sense_buffers + index); 142} 143 144static __inline struct bt_ccb* btgetccb(struct bt_softc *bt); 145static __inline void btfreeccb(struct bt_softc *bt, 146 struct bt_ccb *bccb); 147static void btallocccbs(struct bt_softc *bt); 148static bus_dmamap_callback_t btexecuteccb; 149static void btdone(struct bt_softc *bt, struct bt_ccb *bccb, 150 bt_mbi_comp_code_t comp_code); 151 152/* Host adapter command functions */ 153static int btreset(struct bt_softc* bt, int hard_reset); 154 155/* Initialization functions */ 156static int btinitmboxes(struct bt_softc *bt); 157static bus_dmamap_callback_t btmapmboxes; 158static bus_dmamap_callback_t btmapccbs; 159static bus_dmamap_callback_t btmapsgs; 160 161/* Transfer Negotiation Functions */ 162static void btfetchtransinfo(struct bt_softc *bt, 163 struct ccb_trans_settings *cts); 164 165/* CAM SIM entry points */ 166#define ccb_bccb_ptr spriv_ptr0 167#define ccb_bt_ptr spriv_ptr1 168static void btaction(struct cam_sim *sim, union ccb *ccb); 169static void btpoll(struct cam_sim *sim); 170 171/* Our timeout handler */ 172timeout_t bttimeout; 173 174u_long bt_unit = 0; 175 176/* 177 * XXX 178 * Do our own re-probe protection until a configuration 179 * manager can do it for us. This ensures that we don't 180 * reprobe a card already found by the EISA or PCI probes. 181 */ 182struct bt_isa_port bt_isa_ports[] = 183{
| 33 */ 34 35 /* 36 * Special thanks to Leonard N. Zubkoff for writing such a complete and 37 * well documented Mylex/BusLogic MultiMaster driver for Linux. Support 38 * in this driver for the wide range of MultiMaster controllers and 39 * firmware revisions, with their otherwise undocumented quirks, would not 40 * have been possible without his efforts. 41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/malloc.h> 46#include <sys/buf.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49 50/* 51 * XXX It appears that BusLogic PCI adapters go out to lunch if you 52 * attempt to perform memory mapped I/O. 53 */ 54#if 0 55#include "pci.h" 56#if NPCI > 0 57#include <machine/bus_memio.h> 58#endif 59#endif 60#include <machine/bus_pio.h> 61#include <machine/bus.h> 62#include <machine/clock.h> 63 64#include <cam/cam.h> 65#include <cam/cam_ccb.h> 66#include <cam/cam_sim.h> 67#include <cam/cam_xpt_sim.h> 68#include <cam/cam_debug.h> 69 70#include <cam/scsi/scsi_message.h> 71 72#include <vm/vm.h> 73#include <vm/pmap.h> 74 75#include <dev/buslogic/btreg.h> 76 77struct bt_softc *bt_softcs[NBT]; 78 79/* MailBox Management functions */ 80static __inline void btnextinbox(struct bt_softc *bt); 81static __inline void btnextoutbox(struct bt_softc *bt); 82 83static __inline void 84btnextinbox(struct bt_softc *bt) 85{ 86 if (bt->cur_inbox == bt->last_inbox) 87 bt->cur_inbox = bt->in_boxes; 88 else 89 bt->cur_inbox++; 90} 91 92static __inline void 93btnextoutbox(struct bt_softc *bt) 94{ 95 if (bt->cur_outbox == bt->last_outbox) 96 bt->cur_outbox = bt->out_boxes; 97 else 98 bt->cur_outbox++; 99} 100 101/* CCB Mangement functions */ 102static __inline u_int32_t btccbvtop(struct bt_softc *bt, 103 struct bt_ccb *bccb); 104static __inline struct bt_ccb* btccbptov(struct bt_softc *bt, 105 u_int32_t ccb_addr); 106static __inline u_int32_t btsensepaddr(struct bt_softc *bt, 107 struct bt_ccb *bccb); 108static __inline struct scsi_sense_data* btsensevaddr(struct bt_softc *bt, 109 struct bt_ccb *bccb); 110 111static __inline u_int32_t 112btccbvtop(struct bt_softc *bt, struct bt_ccb *bccb) 113{ 114 return (bt->bt_ccb_physbase 115 + (u_int32_t)((caddr_t)bccb - (caddr_t)bt->bt_ccb_array)); 116} 117 118static __inline struct bt_ccb * 119btccbptov(struct bt_softc *bt, u_int32_t ccb_addr) 120{ 121 return (bt->bt_ccb_array + 122 ((struct bt_ccb*)ccb_addr-(struct bt_ccb*)bt->bt_ccb_physbase)); 123} 124 125static __inline u_int32_t 126btsensepaddr(struct bt_softc *bt, struct bt_ccb *bccb) 127{ 128 u_int index; 129 130 index = (u_int)(bccb - bt->bt_ccb_array); 131 return (bt->sense_buffers_physbase 132 + (index * sizeof(struct scsi_sense_data))); 133} 134 135static __inline struct scsi_sense_data * 136btsensevaddr(struct bt_softc *bt, struct bt_ccb *bccb) 137{ 138 u_int index; 139 140 index = (u_int)(bccb - bt->bt_ccb_array); 141 return (bt->sense_buffers + index); 142} 143 144static __inline struct bt_ccb* btgetccb(struct bt_softc *bt); 145static __inline void btfreeccb(struct bt_softc *bt, 146 struct bt_ccb *bccb); 147static void btallocccbs(struct bt_softc *bt); 148static bus_dmamap_callback_t btexecuteccb; 149static void btdone(struct bt_softc *bt, struct bt_ccb *bccb, 150 bt_mbi_comp_code_t comp_code); 151 152/* Host adapter command functions */ 153static int btreset(struct bt_softc* bt, int hard_reset); 154 155/* Initialization functions */ 156static int btinitmboxes(struct bt_softc *bt); 157static bus_dmamap_callback_t btmapmboxes; 158static bus_dmamap_callback_t btmapccbs; 159static bus_dmamap_callback_t btmapsgs; 160 161/* Transfer Negotiation Functions */ 162static void btfetchtransinfo(struct bt_softc *bt, 163 struct ccb_trans_settings *cts); 164 165/* CAM SIM entry points */ 166#define ccb_bccb_ptr spriv_ptr0 167#define ccb_bt_ptr spriv_ptr1 168static void btaction(struct cam_sim *sim, union ccb *ccb); 169static void btpoll(struct cam_sim *sim); 170 171/* Our timeout handler */ 172timeout_t bttimeout; 173 174u_long bt_unit = 0; 175 176/* 177 * XXX 178 * Do our own re-probe protection until a configuration 179 * manager can do it for us. This ensures that we don't 180 * reprobe a card already found by the EISA or PCI probes. 181 */ 182struct bt_isa_port bt_isa_ports[] = 183{
|
184 { 0x330, 0 }, 185 { 0x334, 0 }, 186 { 0x230, 0 }, 187 { 0x234, 0 }, 188 { 0x130, 0 }, 189 { 0x134, 0 }
| 184 { 0x130, 0, 4 }, 185 { 0x134, 0, 5 }, 186 { 0x230, 0, 2 }, 187 { 0x234, 0, 3 }, 188 { 0x330, 0, 0 }, 189 { 0x334, 0, 1 }
|
190}; 191
| 190}; 191
|
| 192/* 193 * I/O ports listed in the order enumerated by the 194 * card for certain op codes. 195 */ 196u_int16_t bt_board_ports[] = 197{ 198 0x330, 199 0x334, 200 0x230, 201 0x234, 202 0x130, 203 0x134 204}; 205
|
192/* Exported functions */ 193struct bt_softc * 194bt_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh) 195{ 196 struct bt_softc *bt; 197 198 if (unit != BT_TEMP_UNIT) { 199 if (unit >= NBT) { 200 printf("bt: unit number (%d) too high\n", unit); 201 return NULL; 202 } 203 204 /* 205 * Allocate a storage area for us 206 */ 207 if (bt_softcs[unit]) { 208 printf("bt%d: memory already allocated\n", unit); 209 return NULL; 210 } 211 } 212 213 bt = malloc(sizeof(struct bt_softc), M_DEVBUF, M_NOWAIT); 214 if (!bt) { 215 printf("bt%d: cannot malloc!\n", unit); 216 return NULL; 217 } 218 bzero(bt, sizeof(struct bt_softc)); 219 SLIST_INIT(&bt->free_bt_ccbs); 220 LIST_INIT(&bt->pending_ccbs); 221 SLIST_INIT(&bt->sg_maps); 222 bt->unit = unit; 223 bt->tag = tag; 224 bt->bsh = bsh; 225 226 if (bt->unit != BT_TEMP_UNIT) { 227 bt_softcs[unit] = bt; 228 } 229 return (bt); 230} 231 232void 233bt_free(struct bt_softc *bt) 234{ 235 switch (bt->init_level) { 236 default: 237 case 11: 238 bus_dmamap_unload(bt->sense_dmat, bt->sense_dmamap); 239 case 10: 240 bus_dmamem_free(bt->sense_dmat, bt->sense_buffers, 241 bt->sense_dmamap); 242 case 9: 243 bus_dma_tag_destroy(bt->sense_dmat); 244 case 8: 245 { 246 struct sg_map_node *sg_map; 247 248 while ((sg_map = SLIST_FIRST(&bt->sg_maps))!= NULL) { 249 SLIST_REMOVE_HEAD(&bt->sg_maps, links); 250 bus_dmamap_unload(bt->sg_dmat, 251 sg_map->sg_dmamap); 252 bus_dmamem_free(bt->sg_dmat, sg_map->sg_vaddr, 253 sg_map->sg_dmamap); 254 free(sg_map, M_DEVBUF); 255 } 256 bus_dma_tag_destroy(bt->sg_dmat); 257 } 258 case 7: 259 bus_dmamap_unload(bt->ccb_dmat, bt->ccb_dmamap); 260 case 6: 261 bus_dmamem_free(bt->ccb_dmat, bt->bt_ccb_array, 262 bt->ccb_dmamap); 263 bus_dmamap_destroy(bt->ccb_dmat, bt->ccb_dmamap); 264 case 5: 265 bus_dma_tag_destroy(bt->ccb_dmat); 266 case 4: 267 bus_dmamap_unload(bt->mailbox_dmat, bt->mailbox_dmamap); 268 case 3: 269 bus_dmamem_free(bt->mailbox_dmat, bt->in_boxes, 270 bt->mailbox_dmamap); 271 bus_dmamap_destroy(bt->mailbox_dmat, bt->mailbox_dmamap); 272 case 2: 273 bus_dma_tag_destroy(bt->buffer_dmat); 274 case 1: 275 bus_dma_tag_destroy(bt->mailbox_dmat); 276 case 0: 277 break; 278 } 279 if (bt->unit != BT_TEMP_UNIT) { 280 bt_softcs[bt->unit] = NULL; 281 } 282 free(bt, M_DEVBUF); 283} 284 285/* 286 * Probe the adapter and verify that the card is a BusLogic. 287 */ 288int 289bt_probe(struct bt_softc* bt) 290{ 291 esetup_info_data_t esetup_info; 292 u_int status; 293 u_int intstat; 294 u_int geometry; 295 int error; 296 u_int8_t param; 297 298 /* 299 * See if the three I/O ports look reasonable. 300 * Touch the minimal number of registers in the 301 * failure case. 302 */ 303 status = bt_inb(bt, STATUS_REG); 304 if ((status == 0) 305 || (status & (DIAG_ACTIVE|CMD_REG_BUSY| 306 STATUS_REG_RSVD|CMD_INVALID)) != 0) { 307 if (bootverbose) 308 printf("%s: Failed Status Reg Test - %x\n", bt_name(bt), 309 status); 310 return (ENXIO); 311 } 312 313 intstat = bt_inb(bt, INTSTAT_REG); 314 if ((intstat & INTSTAT_REG_RSVD) != 0) { 315 printf("%s: Failed Intstat Reg Test\n", bt_name(bt)); 316 return (ENXIO); 317 } 318 319 geometry = bt_inb(bt, GEOMETRY_REG); 320 if (geometry == 0xFF) { 321 if (bootverbose) 322 printf("%s: Failed Geometry Reg Test\n", bt_name(bt)); 323 return (ENXIO); 324 } 325 326 /* 327 * Looking good so far. Final test is to reset the 328 * adapter and attempt to fetch the extended setup 329 * information. This should filter out all 1542 cards. 330 */ 331 if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) { 332 if (bootverbose) 333 printf("%s: Failed Reset\n", bt_name(bt)); 334 return (ENXIO); 335 } 336 337 param = sizeof(esetup_info); 338 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, ¶m, /*parmlen*/1, 339 (u_int8_t*)&esetup_info, sizeof(esetup_info), 340 DEFAULT_CMD_TIMEOUT); 341 if (error != 0) { 342 return (ENXIO); 343 } 344 345 return (0); 346} 347 348/* 349 * Pull the boards setup information and record it in our softc. 350 */ 351int 352bt_fetch_adapter_info(struct bt_softc *bt) 353{ 354 board_id_data_t board_id; 355 esetup_info_data_t esetup_info; 356 config_data_t config_data; 357 int error; 358 u_int8_t length_param; 359 360 /* First record the firmware version */ 361 error = bt_cmd(bt, BOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0, 362 (u_int8_t*)&board_id, sizeof(board_id), 363 DEFAULT_CMD_TIMEOUT); 364 if (error != 0) { 365 printf("%s: bt_fetch_adapter_info - Failed Get Board Info\n", 366 bt_name(bt)); 367 return (error); 368 } 369 bt->firmware_ver[0] = board_id.firmware_rev_major; 370 bt->firmware_ver[1] = '.'; 371 bt->firmware_ver[2] = board_id.firmware_rev_minor; 372 bt->firmware_ver[3] = '\0'; 373 374 /* 375 * Depending on the firmware major and minor version, 376 * we may be able to fetch additional minor version info. 377 */ 378 if (bt->firmware_ver[0] > '0') { 379 380 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_3DIG, NULL, /*parmlen*/0, 381 (u_int8_t*)&bt->firmware_ver[3], 1, 382 DEFAULT_CMD_TIMEOUT); 383 if (error != 0) { 384 printf("%s: bt_fetch_adapter_info - Failed Get " 385 "Firmware 3rd Digit\n", bt_name(bt)); 386 return (error); 387 } 388 if (bt->firmware_ver[3] == ' ') 389 bt->firmware_ver[3] = '\0'; 390 bt->firmware_ver[4] = '\0'; 391 } 392 393 if (strcmp(bt->firmware_ver, "3.3") >= 0) { 394 395 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_4DIG, NULL, /*parmlen*/0, 396 (u_int8_t*)&bt->firmware_ver[4], 1, 397 DEFAULT_CMD_TIMEOUT); 398 if (error != 0) { 399 printf("%s: bt_fetch_adapter_info - Failed Get " 400 "Firmware 4th Digit\n", bt_name(bt)); 401 return (error); 402 } 403 if (bt->firmware_ver[4] == ' ') 404 bt->firmware_ver[4] = '\0'; 405 bt->firmware_ver[5] = '\0'; 406 } 407 408 /* 409 * Some boards do not handle the "recently documented" 410 * Inquire Board Model Number command correctly or do not give 411 * exact information. Use the Firmware and Extended Setup 412 * information in these cases to come up with the right answer. 413 * The major firmware revision number indicates: 414 * 415 * 5.xx BusLogic "W" Series Host Adapters: 416 * BT-948/958/958D 417 * 4.xx BusLogic "C" Series Host Adapters: 418 * BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF 419 * 3.xx BusLogic "S" Series Host Adapters: 420 * BT-747S/747D/757S/757D/445S/545S/542D 421 * BT-542B/742A (revision H) 422 * 2.xx BusLogic "A" Series Host Adapters: 423 * BT-542B/742A (revision G and below) 424 * 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter 425 */ 426 length_param = sizeof(esetup_info); 427 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &length_param, /*parmlen*/1, 428 (u_int8_t*)&esetup_info, sizeof(esetup_info), 429 DEFAULT_CMD_TIMEOUT); 430 if (error != 0) { 431 return (error); 432 } 433 434 bt->bios_addr = esetup_info.bios_addr << 12; 435 436 if (esetup_info.bus_type == 'A' 437 && bt->firmware_ver[0] == '2') { 438 strcpy(bt->model, "542B"); 439 } else if (esetup_info.bus_type == 'E' 440 && (strncmp(bt->firmware_ver, "2.1", 3) == 0 441 || strncmp(bt->firmware_ver, "2.20", 4) == 0)) { 442 strcpy(bt->model, "742A"); 443 } else if (esetup_info.bus_type == 'E' 444 && bt->firmware_ver[0] == '0') { 445 /* AMI FastDisk EISA Series 441 0.x */ 446 strcpy(bt->model, "747A"); 447 } else { 448 ha_model_data_t model_data; 449 int i; 450 451 length_param = sizeof(model_data); 452 error = bt_cmd(bt, BOP_INQUIRE_MODEL, &length_param, 1, 453 (u_int8_t*)&model_data, sizeof(model_data), 454 DEFAULT_CMD_TIMEOUT); 455 if (error != 0) { 456 printf("%s: bt_fetch_adapter_info - Failed Inquire " 457 "Model Number\n", bt_name(bt)); 458 return (error); 459 } 460 for (i = 0; i < sizeof(model_data.ascii_model); i++) { 461 bt->model[i] = model_data.ascii_model[i]; 462 if (bt->model[i] == ' ') 463 break; 464 } 465 bt->model[i] = '\0'; 466 } 467 468 /* SG element limits */ 469 bt->max_sg = esetup_info.max_sg; 470 471 /* Set feature flags */ 472 bt->wide_bus = esetup_info.wide_bus; 473 bt->diff_bus = esetup_info.diff_bus; 474 bt->ultra_scsi = esetup_info.ultra_scsi; 475 476 if ((bt->firmware_ver[0] == '5') 477 || (bt->firmware_ver[0] == '4' && bt->wide_bus)) 478 bt->extended_lun = TRUE; 479 480 bt->strict_rr = (strcmp(bt->firmware_ver, "3.31") >= 0); 481 482 bt->extended_trans = 483 ((bt_inb(bt, GEOMETRY_REG) & EXTENDED_TRANSLATION) != 0); 484 485 /* 486 * Determine max CCB count and whether tagged queuing is 487 * available based on controller type. Tagged queuing 488 * only works on 'W' series adapters, 'C' series adapters 489 * with firmware of rev 4.42 and higher, and 'S' series 490 * adapters with firmware of rev 3.35 and higher. The 491 * maximum CCB counts are as follows: 492 * 493 * 192 BT-948/958/958D 494 * 100 BT-946C/956C/956CD/747C/757C/757CD/445C 495 * 50 BT-545C/540CF 496 * 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A 497 */ 498 if (bt->firmware_ver[0] == '5') { 499 bt->max_ccbs = 192; 500 bt->tag_capable = TRUE; 501 } else if (bt->firmware_ver[0] == '4') { 502 if (bt->model[0] == '5') 503 bt->max_ccbs = 50; 504 else 505 bt->max_ccbs = 100; 506 bt->tag_capable = (strcmp(bt->firmware_ver, "4.22") >= 0); 507 } else { 508 bt->max_ccbs = 30; 509 if (bt->firmware_ver[0] == '3' 510 && (strcmp(bt->firmware_ver, "3.35") >= 0)) 511 bt->tag_capable = TRUE; 512 else 513 bt->tag_capable = FALSE; 514 } 515 516 if (bt->tag_capable != FALSE) 517 bt->tags_permitted = ALL_TARGETS; 518 519 /* Determine Sync/Wide/Disc settings */ 520 if (bt->firmware_ver[0] >= '4') { 521 auto_scsi_data_t auto_scsi_data; 522 fetch_lram_params_t fetch_lram_params; 523 int error; 524 525 /* 526 * These settings are stored in the 527 * AutoSCSI data in LRAM of 'W' and 'C' 528 * adapters. 529 */ 530 fetch_lram_params.offset = AUTO_SCSI_BYTE_OFFSET; 531 fetch_lram_params.response_len = sizeof(auto_scsi_data); 532 error = bt_cmd(bt, BOP_FETCH_LRAM, 533 (u_int8_t*)&fetch_lram_params, 534 sizeof(fetch_lram_params), 535 (u_int8_t*)&auto_scsi_data, 536 sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT); 537 538 if (error != 0) { 539 printf("%s: bt_fetch_adapter_info - Failed " 540 "Get Auto SCSI Info\n", bt_name(bt)); 541 return (error); 542 } 543 544 bt->disc_permitted = auto_scsi_data.low_disc_permitted 545 | (auto_scsi_data.high_disc_permitted << 8); 546 bt->sync_permitted = auto_scsi_data.low_sync_permitted 547 | (auto_scsi_data.high_sync_permitted << 8); 548 bt->fast_permitted = auto_scsi_data.low_fast_permitted 549 | (auto_scsi_data.high_fast_permitted << 8); 550 bt->ultra_permitted = auto_scsi_data.low_ultra_permitted 551 | (auto_scsi_data.high_ultra_permitted << 8); 552 bt->wide_permitted = auto_scsi_data.low_wide_permitted 553 | (auto_scsi_data.high_wide_permitted << 8); 554 555 if (bt->ultra_scsi == FALSE) 556 bt->ultra_permitted = 0; 557 558 if (bt->wide_bus == FALSE) 559 bt->wide_permitted = 0; 560 } else { 561 /* 562 * 'S' and 'A' series have this information in the setup 563 * information structure. 564 */ 565 setup_data_t setup_info; 566 567 length_param = sizeof(setup_info); 568 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, &length_param, 569 /*paramlen*/1, (u_int8_t*)&setup_info, 570 sizeof(setup_info), DEFAULT_CMD_TIMEOUT); 571 572 if (error != 0) { 573 printf("%s: bt_fetch_adapter_info - Failed " 574 "Get Setup Info\n", bt_name(bt)); 575 return (error); 576 } 577 578 if (setup_info.initiate_sync != 0) { 579 bt->sync_permitted = ALL_TARGETS; 580 581 if (bt->model[0] == '7') { 582 if (esetup_info.sync_neg10MB != 0) 583 bt->fast_permitted = ALL_TARGETS; 584 if (strcmp(bt->model, "757") == 0) 585 bt->wide_permitted = ALL_TARGETS; 586 } 587 } 588 bt->disc_permitted = ALL_TARGETS; 589 } 590 591 /* We need as many mailboxes as we can have ccbs */ 592 bt->num_boxes = bt->max_ccbs; 593 594 /* Determine our SCSI ID */ 595 596 error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 597 (u_int8_t*)&config_data, sizeof(config_data), 598 DEFAULT_CMD_TIMEOUT); 599 if (error != 0) { 600 printf("%s: bt_fetch_adapter_info - Failed Get Config\n", 601 bt_name(bt)); 602 return (error); 603 } 604 bt->scsi_id = config_data.scsi_id; 605 606 return (0); 607} 608 609/* 610 * Start the board, ready for normal operation 611 */ 612int 613bt_init(struct bt_softc* bt) 614{ 615 /* Announce the Adapter */ 616 printf("%s: BT-%s FW Rev. %s ", bt_name(bt), 617 bt->model, bt->firmware_ver); 618 619 if (bt->ultra_scsi != 0) 620 printf("Ultra "); 621 622 if (bt->wide_bus != 0) 623 printf("Wide "); 624 else 625 printf("Narrow "); 626 627 if (bt->diff_bus != 0) 628 printf("Diff "); 629 630 printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", bt->scsi_id, 631 bt->max_ccbs); 632 633 /* 634 * Create our DMA tags. These tags define the kinds of device 635 * accessable memory allocations and memory mappings we will 636 * need to perform during normal operation. 637 * 638 * Unless we need to further restrict the allocation, we rely 639 * on the restrictions of the parent dmat, hence the common 640 * use of MAXADDR and MAXSIZE. 641 */ 642 643 /* DMA tag for mapping buffers into device visible space. */ 644 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 645 /*lowaddr*/BUS_SPACE_MAXADDR, 646 /*highaddr*/BUS_SPACE_MAXADDR, 647 /*filter*/NULL, /*filterarg*/NULL, 648 /*maxsize*/MAXBSIZE, /*nsegments*/BT_NSEG, 649 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 650 /*flags*/BUS_DMA_ALLOCNOW, 651 &bt->buffer_dmat) != 0) { 652 goto error_exit; 653 } 654 655 bt->init_level++; 656 /* DMA tag for our mailboxes */ 657 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 658 /*lowaddr*/BUS_SPACE_MAXADDR, 659 /*highaddr*/BUS_SPACE_MAXADDR, 660 /*filter*/NULL, /*filterarg*/NULL, 661 bt->num_boxes * (sizeof(bt_mbox_in_t) 662 + sizeof(bt_mbox_out_t)), 663 /*nsegments*/1, 664 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 665 /*flags*/0, &bt->mailbox_dmat) != 0) { 666 goto error_exit; 667 } 668 669 bt->init_level++; 670 671 /* Allocation for our mailboxes */ 672 if (bus_dmamem_alloc(bt->mailbox_dmat, (void **)&bt->out_boxes, 673 BUS_DMA_NOWAIT, &bt->mailbox_dmamap) != 0) { 674 goto error_exit; 675 } 676 677 bt->init_level++; 678 679 /* And permanently map them */ 680 bus_dmamap_load(bt->mailbox_dmat, bt->mailbox_dmamap, 681 bt->out_boxes, 682 bt->num_boxes * (sizeof(bt_mbox_in_t) 683 + sizeof(bt_mbox_out_t)), 684 btmapmboxes, bt, /*flags*/0); 685 686 bt->init_level++; 687 688 bt->in_boxes = (bt_mbox_in_t *)&bt->out_boxes[bt->num_boxes]; 689 690 btinitmboxes(bt); 691 692 /* DMA tag for our ccb structures */ 693 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 694 /*lowaddr*/BUS_SPACE_MAXADDR, 695 /*highaddr*/BUS_SPACE_MAXADDR, 696 /*filter*/NULL, /*filterarg*/NULL, 697 bt->max_ccbs * sizeof(struct bt_ccb), 698 /*nsegments*/1, 699 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 700 /*flags*/0, &bt->ccb_dmat) != 0) { 701 goto error_exit; 702 } 703 704 bt->init_level++; 705 706 /* Allocation for our ccbs */ 707 if (bus_dmamem_alloc(bt->ccb_dmat, (void **)&bt->bt_ccb_array, 708 BUS_DMA_NOWAIT, &bt->ccb_dmamap) != 0) { 709 goto error_exit; 710 } 711 712 bt->init_level++; 713 714 /* And permanently map them */ 715 bus_dmamap_load(bt->ccb_dmat, bt->ccb_dmamap, 716 bt->bt_ccb_array, 717 bt->max_ccbs * sizeof(struct bt_ccb), 718 btmapccbs, bt, /*flags*/0); 719 720 bt->init_level++; 721 722 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 723 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 724 /*lowaddr*/BUS_SPACE_MAXADDR, 725 /*highaddr*/BUS_SPACE_MAXADDR, 726 /*filter*/NULL, /*filterarg*/NULL, 727 PAGE_SIZE, /*nsegments*/1, 728 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 729 /*flags*/0, &bt->sg_dmat) != 0) { 730 goto error_exit; 731 } 732 733 bt->init_level++; 734 735 /* Perform initial CCB allocation */ 736 bzero(bt->bt_ccb_array, bt->max_ccbs * sizeof(struct bt_ccb)); 737 btallocccbs(bt); 738 739 if (bt->num_ccbs == 0) { 740 printf("%s: bt_init - Unable to allocate initial ccbs\n", 741 bt_name(bt)); 742 goto error_exit; 743 } 744 745 /* 746 * Note that we are going and return (to probe) 747 */ 748 return 0; 749 750error_exit: 751 752 return (ENXIO); 753} 754 755int 756bt_attach(struct bt_softc *bt) 757{ 758 int tagged_dev_openings; 759 struct cam_devq *devq; 760 761 /* 762 * We reserve 1 ccb for error recovery, so don't 763 * tell the XPT about it. 764 */ 765 if (bt->tag_capable != 0) 766 tagged_dev_openings = bt->max_ccbs - 1; 767 else 768 tagged_dev_openings = 0; 769 770 /* 771 * Create the device queue for our SIM. 772 */ 773 devq = cam_simq_alloc(bt->max_ccbs - 1); 774 if (devq == NULL) 775 return (ENOMEM); 776 777 /* 778 * Construct our SIM entry 779 */ 780 bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt, bt->unit, 781 2, tagged_dev_openings, devq); 782 if (bt->sim == NULL) { 783 cam_simq_free(devq); 784 return (ENOMEM); 785 } 786 787 if (xpt_bus_register(bt->sim, 0) != CAM_SUCCESS) { 788 cam_sim_free(bt->sim, /*free_devq*/TRUE); 789 return (ENXIO); 790 } 791 792 if (xpt_create_path(&bt->path, /*periph*/NULL, 793 cam_sim_path(bt->sim), CAM_TARGET_WILDCARD, 794 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 795 xpt_bus_deregister(cam_sim_path(bt->sim)); 796 cam_sim_free(bt->sim, /*free_devq*/TRUE); 797 return (ENXIO); 798 } 799 800 return (0); 801} 802 803char * 804bt_name(struct bt_softc *bt) 805{ 806 static char name[10]; 807 808 sprintf(name, "bt%d", bt->unit); 809 return (name); 810} 811 812int 813bt_check_probed_iop(u_int ioport) 814{ 815 u_int i; 816
| 206/* Exported functions */ 207struct bt_softc * 208bt_alloc(int unit, bus_space_tag_t tag, bus_space_handle_t bsh) 209{ 210 struct bt_softc *bt; 211 212 if (unit != BT_TEMP_UNIT) { 213 if (unit >= NBT) { 214 printf("bt: unit number (%d) too high\n", unit); 215 return NULL; 216 } 217 218 /* 219 * Allocate a storage area for us 220 */ 221 if (bt_softcs[unit]) { 222 printf("bt%d: memory already allocated\n", unit); 223 return NULL; 224 } 225 } 226 227 bt = malloc(sizeof(struct bt_softc), M_DEVBUF, M_NOWAIT); 228 if (!bt) { 229 printf("bt%d: cannot malloc!\n", unit); 230 return NULL; 231 } 232 bzero(bt, sizeof(struct bt_softc)); 233 SLIST_INIT(&bt->free_bt_ccbs); 234 LIST_INIT(&bt->pending_ccbs); 235 SLIST_INIT(&bt->sg_maps); 236 bt->unit = unit; 237 bt->tag = tag; 238 bt->bsh = bsh; 239 240 if (bt->unit != BT_TEMP_UNIT) { 241 bt_softcs[unit] = bt; 242 } 243 return (bt); 244} 245 246void 247bt_free(struct bt_softc *bt) 248{ 249 switch (bt->init_level) { 250 default: 251 case 11: 252 bus_dmamap_unload(bt->sense_dmat, bt->sense_dmamap); 253 case 10: 254 bus_dmamem_free(bt->sense_dmat, bt->sense_buffers, 255 bt->sense_dmamap); 256 case 9: 257 bus_dma_tag_destroy(bt->sense_dmat); 258 case 8: 259 { 260 struct sg_map_node *sg_map; 261 262 while ((sg_map = SLIST_FIRST(&bt->sg_maps))!= NULL) { 263 SLIST_REMOVE_HEAD(&bt->sg_maps, links); 264 bus_dmamap_unload(bt->sg_dmat, 265 sg_map->sg_dmamap); 266 bus_dmamem_free(bt->sg_dmat, sg_map->sg_vaddr, 267 sg_map->sg_dmamap); 268 free(sg_map, M_DEVBUF); 269 } 270 bus_dma_tag_destroy(bt->sg_dmat); 271 } 272 case 7: 273 bus_dmamap_unload(bt->ccb_dmat, bt->ccb_dmamap); 274 case 6: 275 bus_dmamem_free(bt->ccb_dmat, bt->bt_ccb_array, 276 bt->ccb_dmamap); 277 bus_dmamap_destroy(bt->ccb_dmat, bt->ccb_dmamap); 278 case 5: 279 bus_dma_tag_destroy(bt->ccb_dmat); 280 case 4: 281 bus_dmamap_unload(bt->mailbox_dmat, bt->mailbox_dmamap); 282 case 3: 283 bus_dmamem_free(bt->mailbox_dmat, bt->in_boxes, 284 bt->mailbox_dmamap); 285 bus_dmamap_destroy(bt->mailbox_dmat, bt->mailbox_dmamap); 286 case 2: 287 bus_dma_tag_destroy(bt->buffer_dmat); 288 case 1: 289 bus_dma_tag_destroy(bt->mailbox_dmat); 290 case 0: 291 break; 292 } 293 if (bt->unit != BT_TEMP_UNIT) { 294 bt_softcs[bt->unit] = NULL; 295 } 296 free(bt, M_DEVBUF); 297} 298 299/* 300 * Probe the adapter and verify that the card is a BusLogic. 301 */ 302int 303bt_probe(struct bt_softc* bt) 304{ 305 esetup_info_data_t esetup_info; 306 u_int status; 307 u_int intstat; 308 u_int geometry; 309 int error; 310 u_int8_t param; 311 312 /* 313 * See if the three I/O ports look reasonable. 314 * Touch the minimal number of registers in the 315 * failure case. 316 */ 317 status = bt_inb(bt, STATUS_REG); 318 if ((status == 0) 319 || (status & (DIAG_ACTIVE|CMD_REG_BUSY| 320 STATUS_REG_RSVD|CMD_INVALID)) != 0) { 321 if (bootverbose) 322 printf("%s: Failed Status Reg Test - %x\n", bt_name(bt), 323 status); 324 return (ENXIO); 325 } 326 327 intstat = bt_inb(bt, INTSTAT_REG); 328 if ((intstat & INTSTAT_REG_RSVD) != 0) { 329 printf("%s: Failed Intstat Reg Test\n", bt_name(bt)); 330 return (ENXIO); 331 } 332 333 geometry = bt_inb(bt, GEOMETRY_REG); 334 if (geometry == 0xFF) { 335 if (bootverbose) 336 printf("%s: Failed Geometry Reg Test\n", bt_name(bt)); 337 return (ENXIO); 338 } 339 340 /* 341 * Looking good so far. Final test is to reset the 342 * adapter and attempt to fetch the extended setup 343 * information. This should filter out all 1542 cards. 344 */ 345 if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) { 346 if (bootverbose) 347 printf("%s: Failed Reset\n", bt_name(bt)); 348 return (ENXIO); 349 } 350 351 param = sizeof(esetup_info); 352 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, ¶m, /*parmlen*/1, 353 (u_int8_t*)&esetup_info, sizeof(esetup_info), 354 DEFAULT_CMD_TIMEOUT); 355 if (error != 0) { 356 return (ENXIO); 357 } 358 359 return (0); 360} 361 362/* 363 * Pull the boards setup information and record it in our softc. 364 */ 365int 366bt_fetch_adapter_info(struct bt_softc *bt) 367{ 368 board_id_data_t board_id; 369 esetup_info_data_t esetup_info; 370 config_data_t config_data; 371 int error; 372 u_int8_t length_param; 373 374 /* First record the firmware version */ 375 error = bt_cmd(bt, BOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0, 376 (u_int8_t*)&board_id, sizeof(board_id), 377 DEFAULT_CMD_TIMEOUT); 378 if (error != 0) { 379 printf("%s: bt_fetch_adapter_info - Failed Get Board Info\n", 380 bt_name(bt)); 381 return (error); 382 } 383 bt->firmware_ver[0] = board_id.firmware_rev_major; 384 bt->firmware_ver[1] = '.'; 385 bt->firmware_ver[2] = board_id.firmware_rev_minor; 386 bt->firmware_ver[3] = '\0'; 387 388 /* 389 * Depending on the firmware major and minor version, 390 * we may be able to fetch additional minor version info. 391 */ 392 if (bt->firmware_ver[0] > '0') { 393 394 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_3DIG, NULL, /*parmlen*/0, 395 (u_int8_t*)&bt->firmware_ver[3], 1, 396 DEFAULT_CMD_TIMEOUT); 397 if (error != 0) { 398 printf("%s: bt_fetch_adapter_info - Failed Get " 399 "Firmware 3rd Digit\n", bt_name(bt)); 400 return (error); 401 } 402 if (bt->firmware_ver[3] == ' ') 403 bt->firmware_ver[3] = '\0'; 404 bt->firmware_ver[4] = '\0'; 405 } 406 407 if (strcmp(bt->firmware_ver, "3.3") >= 0) { 408 409 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_4DIG, NULL, /*parmlen*/0, 410 (u_int8_t*)&bt->firmware_ver[4], 1, 411 DEFAULT_CMD_TIMEOUT); 412 if (error != 0) { 413 printf("%s: bt_fetch_adapter_info - Failed Get " 414 "Firmware 4th Digit\n", bt_name(bt)); 415 return (error); 416 } 417 if (bt->firmware_ver[4] == ' ') 418 bt->firmware_ver[4] = '\0'; 419 bt->firmware_ver[5] = '\0'; 420 } 421 422 /* 423 * Some boards do not handle the "recently documented" 424 * Inquire Board Model Number command correctly or do not give 425 * exact information. Use the Firmware and Extended Setup 426 * information in these cases to come up with the right answer. 427 * The major firmware revision number indicates: 428 * 429 * 5.xx BusLogic "W" Series Host Adapters: 430 * BT-948/958/958D 431 * 4.xx BusLogic "C" Series Host Adapters: 432 * BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF 433 * 3.xx BusLogic "S" Series Host Adapters: 434 * BT-747S/747D/757S/757D/445S/545S/542D 435 * BT-542B/742A (revision H) 436 * 2.xx BusLogic "A" Series Host Adapters: 437 * BT-542B/742A (revision G and below) 438 * 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter 439 */ 440 length_param = sizeof(esetup_info); 441 error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &length_param, /*parmlen*/1, 442 (u_int8_t*)&esetup_info, sizeof(esetup_info), 443 DEFAULT_CMD_TIMEOUT); 444 if (error != 0) { 445 return (error); 446 } 447 448 bt->bios_addr = esetup_info.bios_addr << 12; 449 450 if (esetup_info.bus_type == 'A' 451 && bt->firmware_ver[0] == '2') { 452 strcpy(bt->model, "542B"); 453 } else if (esetup_info.bus_type == 'E' 454 && (strncmp(bt->firmware_ver, "2.1", 3) == 0 455 || strncmp(bt->firmware_ver, "2.20", 4) == 0)) { 456 strcpy(bt->model, "742A"); 457 } else if (esetup_info.bus_type == 'E' 458 && bt->firmware_ver[0] == '0') { 459 /* AMI FastDisk EISA Series 441 0.x */ 460 strcpy(bt->model, "747A"); 461 } else { 462 ha_model_data_t model_data; 463 int i; 464 465 length_param = sizeof(model_data); 466 error = bt_cmd(bt, BOP_INQUIRE_MODEL, &length_param, 1, 467 (u_int8_t*)&model_data, sizeof(model_data), 468 DEFAULT_CMD_TIMEOUT); 469 if (error != 0) { 470 printf("%s: bt_fetch_adapter_info - Failed Inquire " 471 "Model Number\n", bt_name(bt)); 472 return (error); 473 } 474 for (i = 0; i < sizeof(model_data.ascii_model); i++) { 475 bt->model[i] = model_data.ascii_model[i]; 476 if (bt->model[i] == ' ') 477 break; 478 } 479 bt->model[i] = '\0'; 480 } 481 482 /* SG element limits */ 483 bt->max_sg = esetup_info.max_sg; 484 485 /* Set feature flags */ 486 bt->wide_bus = esetup_info.wide_bus; 487 bt->diff_bus = esetup_info.diff_bus; 488 bt->ultra_scsi = esetup_info.ultra_scsi; 489 490 if ((bt->firmware_ver[0] == '5') 491 || (bt->firmware_ver[0] == '4' && bt->wide_bus)) 492 bt->extended_lun = TRUE; 493 494 bt->strict_rr = (strcmp(bt->firmware_ver, "3.31") >= 0); 495 496 bt->extended_trans = 497 ((bt_inb(bt, GEOMETRY_REG) & EXTENDED_TRANSLATION) != 0); 498 499 /* 500 * Determine max CCB count and whether tagged queuing is 501 * available based on controller type. Tagged queuing 502 * only works on 'W' series adapters, 'C' series adapters 503 * with firmware of rev 4.42 and higher, and 'S' series 504 * adapters with firmware of rev 3.35 and higher. The 505 * maximum CCB counts are as follows: 506 * 507 * 192 BT-948/958/958D 508 * 100 BT-946C/956C/956CD/747C/757C/757CD/445C 509 * 50 BT-545C/540CF 510 * 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A 511 */ 512 if (bt->firmware_ver[0] == '5') { 513 bt->max_ccbs = 192; 514 bt->tag_capable = TRUE; 515 } else if (bt->firmware_ver[0] == '4') { 516 if (bt->model[0] == '5') 517 bt->max_ccbs = 50; 518 else 519 bt->max_ccbs = 100; 520 bt->tag_capable = (strcmp(bt->firmware_ver, "4.22") >= 0); 521 } else { 522 bt->max_ccbs = 30; 523 if (bt->firmware_ver[0] == '3' 524 && (strcmp(bt->firmware_ver, "3.35") >= 0)) 525 bt->tag_capable = TRUE; 526 else 527 bt->tag_capable = FALSE; 528 } 529 530 if (bt->tag_capable != FALSE) 531 bt->tags_permitted = ALL_TARGETS; 532 533 /* Determine Sync/Wide/Disc settings */ 534 if (bt->firmware_ver[0] >= '4') { 535 auto_scsi_data_t auto_scsi_data; 536 fetch_lram_params_t fetch_lram_params; 537 int error; 538 539 /* 540 * These settings are stored in the 541 * AutoSCSI data in LRAM of 'W' and 'C' 542 * adapters. 543 */ 544 fetch_lram_params.offset = AUTO_SCSI_BYTE_OFFSET; 545 fetch_lram_params.response_len = sizeof(auto_scsi_data); 546 error = bt_cmd(bt, BOP_FETCH_LRAM, 547 (u_int8_t*)&fetch_lram_params, 548 sizeof(fetch_lram_params), 549 (u_int8_t*)&auto_scsi_data, 550 sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT); 551 552 if (error != 0) { 553 printf("%s: bt_fetch_adapter_info - Failed " 554 "Get Auto SCSI Info\n", bt_name(bt)); 555 return (error); 556 } 557 558 bt->disc_permitted = auto_scsi_data.low_disc_permitted 559 | (auto_scsi_data.high_disc_permitted << 8); 560 bt->sync_permitted = auto_scsi_data.low_sync_permitted 561 | (auto_scsi_data.high_sync_permitted << 8); 562 bt->fast_permitted = auto_scsi_data.low_fast_permitted 563 | (auto_scsi_data.high_fast_permitted << 8); 564 bt->ultra_permitted = auto_scsi_data.low_ultra_permitted 565 | (auto_scsi_data.high_ultra_permitted << 8); 566 bt->wide_permitted = auto_scsi_data.low_wide_permitted 567 | (auto_scsi_data.high_wide_permitted << 8); 568 569 if (bt->ultra_scsi == FALSE) 570 bt->ultra_permitted = 0; 571 572 if (bt->wide_bus == FALSE) 573 bt->wide_permitted = 0; 574 } else { 575 /* 576 * 'S' and 'A' series have this information in the setup 577 * information structure. 578 */ 579 setup_data_t setup_info; 580 581 length_param = sizeof(setup_info); 582 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, &length_param, 583 /*paramlen*/1, (u_int8_t*)&setup_info, 584 sizeof(setup_info), DEFAULT_CMD_TIMEOUT); 585 586 if (error != 0) { 587 printf("%s: bt_fetch_adapter_info - Failed " 588 "Get Setup Info\n", bt_name(bt)); 589 return (error); 590 } 591 592 if (setup_info.initiate_sync != 0) { 593 bt->sync_permitted = ALL_TARGETS; 594 595 if (bt->model[0] == '7') { 596 if (esetup_info.sync_neg10MB != 0) 597 bt->fast_permitted = ALL_TARGETS; 598 if (strcmp(bt->model, "757") == 0) 599 bt->wide_permitted = ALL_TARGETS; 600 } 601 } 602 bt->disc_permitted = ALL_TARGETS; 603 } 604 605 /* We need as many mailboxes as we can have ccbs */ 606 bt->num_boxes = bt->max_ccbs; 607 608 /* Determine our SCSI ID */ 609 610 error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0, 611 (u_int8_t*)&config_data, sizeof(config_data), 612 DEFAULT_CMD_TIMEOUT); 613 if (error != 0) { 614 printf("%s: bt_fetch_adapter_info - Failed Get Config\n", 615 bt_name(bt)); 616 return (error); 617 } 618 bt->scsi_id = config_data.scsi_id; 619 620 return (0); 621} 622 623/* 624 * Start the board, ready for normal operation 625 */ 626int 627bt_init(struct bt_softc* bt) 628{ 629 /* Announce the Adapter */ 630 printf("%s: BT-%s FW Rev. %s ", bt_name(bt), 631 bt->model, bt->firmware_ver); 632 633 if (bt->ultra_scsi != 0) 634 printf("Ultra "); 635 636 if (bt->wide_bus != 0) 637 printf("Wide "); 638 else 639 printf("Narrow "); 640 641 if (bt->diff_bus != 0) 642 printf("Diff "); 643 644 printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", bt->scsi_id, 645 bt->max_ccbs); 646 647 /* 648 * Create our DMA tags. These tags define the kinds of device 649 * accessable memory allocations and memory mappings we will 650 * need to perform during normal operation. 651 * 652 * Unless we need to further restrict the allocation, we rely 653 * on the restrictions of the parent dmat, hence the common 654 * use of MAXADDR and MAXSIZE. 655 */ 656 657 /* DMA tag for mapping buffers into device visible space. */ 658 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 659 /*lowaddr*/BUS_SPACE_MAXADDR, 660 /*highaddr*/BUS_SPACE_MAXADDR, 661 /*filter*/NULL, /*filterarg*/NULL, 662 /*maxsize*/MAXBSIZE, /*nsegments*/BT_NSEG, 663 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 664 /*flags*/BUS_DMA_ALLOCNOW, 665 &bt->buffer_dmat) != 0) { 666 goto error_exit; 667 } 668 669 bt->init_level++; 670 /* DMA tag for our mailboxes */ 671 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 672 /*lowaddr*/BUS_SPACE_MAXADDR, 673 /*highaddr*/BUS_SPACE_MAXADDR, 674 /*filter*/NULL, /*filterarg*/NULL, 675 bt->num_boxes * (sizeof(bt_mbox_in_t) 676 + sizeof(bt_mbox_out_t)), 677 /*nsegments*/1, 678 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 679 /*flags*/0, &bt->mailbox_dmat) != 0) { 680 goto error_exit; 681 } 682 683 bt->init_level++; 684 685 /* Allocation for our mailboxes */ 686 if (bus_dmamem_alloc(bt->mailbox_dmat, (void **)&bt->out_boxes, 687 BUS_DMA_NOWAIT, &bt->mailbox_dmamap) != 0) { 688 goto error_exit; 689 } 690 691 bt->init_level++; 692 693 /* And permanently map them */ 694 bus_dmamap_load(bt->mailbox_dmat, bt->mailbox_dmamap, 695 bt->out_boxes, 696 bt->num_boxes * (sizeof(bt_mbox_in_t) 697 + sizeof(bt_mbox_out_t)), 698 btmapmboxes, bt, /*flags*/0); 699 700 bt->init_level++; 701 702 bt->in_boxes = (bt_mbox_in_t *)&bt->out_boxes[bt->num_boxes]; 703 704 btinitmboxes(bt); 705 706 /* DMA tag for our ccb structures */ 707 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 708 /*lowaddr*/BUS_SPACE_MAXADDR, 709 /*highaddr*/BUS_SPACE_MAXADDR, 710 /*filter*/NULL, /*filterarg*/NULL, 711 bt->max_ccbs * sizeof(struct bt_ccb), 712 /*nsegments*/1, 713 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 714 /*flags*/0, &bt->ccb_dmat) != 0) { 715 goto error_exit; 716 } 717 718 bt->init_level++; 719 720 /* Allocation for our ccbs */ 721 if (bus_dmamem_alloc(bt->ccb_dmat, (void **)&bt->bt_ccb_array, 722 BUS_DMA_NOWAIT, &bt->ccb_dmamap) != 0) { 723 goto error_exit; 724 } 725 726 bt->init_level++; 727 728 /* And permanently map them */ 729 bus_dmamap_load(bt->ccb_dmat, bt->ccb_dmamap, 730 bt->bt_ccb_array, 731 bt->max_ccbs * sizeof(struct bt_ccb), 732 btmapccbs, bt, /*flags*/0); 733 734 bt->init_level++; 735 736 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 737 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/0, /*boundary*/0, 738 /*lowaddr*/BUS_SPACE_MAXADDR, 739 /*highaddr*/BUS_SPACE_MAXADDR, 740 /*filter*/NULL, /*filterarg*/NULL, 741 PAGE_SIZE, /*nsegments*/1, 742 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 743 /*flags*/0, &bt->sg_dmat) != 0) { 744 goto error_exit; 745 } 746 747 bt->init_level++; 748 749 /* Perform initial CCB allocation */ 750 bzero(bt->bt_ccb_array, bt->max_ccbs * sizeof(struct bt_ccb)); 751 btallocccbs(bt); 752 753 if (bt->num_ccbs == 0) { 754 printf("%s: bt_init - Unable to allocate initial ccbs\n", 755 bt_name(bt)); 756 goto error_exit; 757 } 758 759 /* 760 * Note that we are going and return (to probe) 761 */ 762 return 0; 763 764error_exit: 765 766 return (ENXIO); 767} 768 769int 770bt_attach(struct bt_softc *bt) 771{ 772 int tagged_dev_openings; 773 struct cam_devq *devq; 774 775 /* 776 * We reserve 1 ccb for error recovery, so don't 777 * tell the XPT about it. 778 */ 779 if (bt->tag_capable != 0) 780 tagged_dev_openings = bt->max_ccbs - 1; 781 else 782 tagged_dev_openings = 0; 783 784 /* 785 * Create the device queue for our SIM. 786 */ 787 devq = cam_simq_alloc(bt->max_ccbs - 1); 788 if (devq == NULL) 789 return (ENOMEM); 790 791 /* 792 * Construct our SIM entry 793 */ 794 bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt, bt->unit, 795 2, tagged_dev_openings, devq); 796 if (bt->sim == NULL) { 797 cam_simq_free(devq); 798 return (ENOMEM); 799 } 800 801 if (xpt_bus_register(bt->sim, 0) != CAM_SUCCESS) { 802 cam_sim_free(bt->sim, /*free_devq*/TRUE); 803 return (ENXIO); 804 } 805 806 if (xpt_create_path(&bt->path, /*periph*/NULL, 807 cam_sim_path(bt->sim), CAM_TARGET_WILDCARD, 808 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 809 xpt_bus_deregister(cam_sim_path(bt->sim)); 810 cam_sim_free(bt->sim, /*free_devq*/TRUE); 811 return (ENXIO); 812 } 813 814 return (0); 815} 816 817char * 818bt_name(struct bt_softc *bt) 819{ 820 static char name[10]; 821 822 sprintf(name, "bt%d", bt->unit); 823 return (name); 824} 825 826int 827bt_check_probed_iop(u_int ioport) 828{ 829 u_int i; 830
|
817 for (i=0; i < BT_NUM_ISAPORTS; i++) {
| 831 for (i = 0; i < BT_NUM_ISAPORTS; i++) {
|
818 if (bt_isa_ports[i].addr == ioport) { 819 if (bt_isa_ports[i].probed != 0) 820 return (1); 821 else { 822 return (0); 823 } 824 } 825 } 826 return (1); 827} 828
| 832 if (bt_isa_ports[i].addr == ioport) { 833 if (bt_isa_ports[i].probed != 0) 834 return (1); 835 else { 836 return (0); 837 } 838 } 839 } 840 return (1); 841} 842
|
829u_int 830bt_fetch_isa_iop(isa_compat_io_t port) 831{ 832 return (bt_isa_ports[port].addr); 833} 834
| |
835void 836bt_mark_probed_bio(isa_compat_io_t port) 837{ 838 if (port < BIO_DISABLED)
| 843void 844bt_mark_probed_bio(isa_compat_io_t port) 845{ 846 if (port < BIO_DISABLED)
|
839 bt_isa_ports[port].probed = 1;
| 847 bt_mark_probed_iop(bt_board_ports[port]);
|
840} 841 842void 843bt_mark_probed_iop(u_int ioport) 844{ 845 u_int i; 846 847 for (i = 0; i < BT_NUM_ISAPORTS; i++) { 848 if (ioport == bt_isa_ports[i].addr) { 849 bt_isa_ports[i].probed = 1; 850 break; 851 } 852 } 853} 854
| 848} 849 850void 851bt_mark_probed_iop(u_int ioport) 852{ 853 u_int i; 854 855 for (i = 0; i < BT_NUM_ISAPORTS; i++) { 856 if (ioport == bt_isa_ports[i].addr) { 857 bt_isa_ports[i].probed = 1; 858 break; 859 } 860 } 861} 862
|
| 863void 864bt_find_probe_range(int ioport, int *port_index, int *max_port_index) 865{ 866 if (ioport > 0) { 867 int i; 868 869 for (i = 0;i < BT_NUM_ISAPORTS; i++) 870 if (ioport <= bt_isa_ports[i].addr) 871 break; 872 if ((i >= BT_NUM_ISAPORTS) 873 || (ioport != bt_isa_ports[i].addr)) { 874 printf(" 875bt_isa_probe: Invalid baseport of 0x%x specified. 876bt_isa_probe: Nearest valid baseport is 0x%x. 877bt_isa_probe: Failing probe.\n", 878 ioport, 879 (i < BT_NUM_ISAPORTS) 880 ? bt_isa_ports[i].addr 881 : bt_isa_ports[BT_NUM_ISAPORTS - 1].addr); 882 *port_index = *max_port_index = -1; 883 return; 884 } 885 *port_index = *max_port_index = bt_isa_ports[i].bio; 886 } else { 887 *port_index = 0; 888 *max_port_index = BT_NUM_ISAPORTS - 1; 889 } 890} 891 892int 893bt_iop_from_bio(isa_compat_io_t bio_index) 894{ 895 if (bio_index >= 0 && bio_index < BT_NUM_ISAPORTS) 896 return (bt_board_ports[bio_index]); 897 return (-1); 898} 899 900
|
855static void 856btallocccbs(struct bt_softc *bt) 857{ 858 struct bt_ccb *next_ccb; 859 struct sg_map_node *sg_map; 860 bus_addr_t physaddr; 861 bt_sg_t *segs; 862 int newcount; 863 int i; 864 865 next_ccb = &bt->bt_ccb_array[bt->num_ccbs]; 866 867 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 868 869 if (sg_map == NULL) 870 return; 871 872 /* Allocate S/G space for the next batch of CCBS */ 873 if (bus_dmamem_alloc(bt->sg_dmat, (void **)&sg_map->sg_vaddr, 874 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 875 free(sg_map, M_DEVBUF); 876 return; 877 } 878 879 SLIST_INSERT_HEAD(&bt->sg_maps, sg_map, links); 880 881 bus_dmamap_load(bt->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 882 PAGE_SIZE, btmapsgs, bt, /*flags*/0); 883 884 segs = sg_map->sg_vaddr; 885 physaddr = sg_map->sg_physaddr; 886 887 newcount = (PAGE_SIZE / (BT_NSEG * sizeof(bt_sg_t))); 888 for (i = 0; bt->num_ccbs < bt->max_ccbs && i < newcount; i++) { 889 int error; 890 891 next_ccb->sg_list = segs; 892 next_ccb->sg_list_phys = physaddr; 893 next_ccb->flags = BCCB_FREE; 894 error = bus_dmamap_create(bt->buffer_dmat, /*flags*/0, 895 &next_ccb->dmamap); 896 if (error != 0) 897 break; 898 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, next_ccb, links); 899 segs += BT_NSEG; 900 physaddr += (BT_NSEG * sizeof(bt_sg_t)); 901 next_ccb++; 902 bt->num_ccbs++; 903 } 904 905 /* Reserve a CCB for error recovery */ 906 if (bt->recovery_bccb == NULL) { 907 bt->recovery_bccb = SLIST_FIRST(&bt->free_bt_ccbs); 908 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links); 909 } 910} 911 912static __inline void 913btfreeccb(struct bt_softc *bt, struct bt_ccb *bccb) 914{ 915 int s; 916 917 s = splcam(); 918 if ((bccb->flags & BCCB_ACTIVE) != 0) 919 LIST_REMOVE(&bccb->ccb->ccb_h, sim_links.le); 920 if (bt->resource_shortage != 0 921 && (bccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 922 bccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 923 bt->resource_shortage = FALSE; 924 } 925 bccb->flags = BCCB_FREE; 926 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, bccb, links);
| 901static void 902btallocccbs(struct bt_softc *bt) 903{ 904 struct bt_ccb *next_ccb; 905 struct sg_map_node *sg_map; 906 bus_addr_t physaddr; 907 bt_sg_t *segs; 908 int newcount; 909 int i; 910 911 next_ccb = &bt->bt_ccb_array[bt->num_ccbs]; 912 913 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT); 914 915 if (sg_map == NULL) 916 return; 917 918 /* Allocate S/G space for the next batch of CCBS */ 919 if (bus_dmamem_alloc(bt->sg_dmat, (void **)&sg_map->sg_vaddr, 920 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 921 free(sg_map, M_DEVBUF); 922 return; 923 } 924 925 SLIST_INSERT_HEAD(&bt->sg_maps, sg_map, links); 926 927 bus_dmamap_load(bt->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 928 PAGE_SIZE, btmapsgs, bt, /*flags*/0); 929 930 segs = sg_map->sg_vaddr; 931 physaddr = sg_map->sg_physaddr; 932 933 newcount = (PAGE_SIZE / (BT_NSEG * sizeof(bt_sg_t))); 934 for (i = 0; bt->num_ccbs < bt->max_ccbs && i < newcount; i++) { 935 int error; 936 937 next_ccb->sg_list = segs; 938 next_ccb->sg_list_phys = physaddr; 939 next_ccb->flags = BCCB_FREE; 940 error = bus_dmamap_create(bt->buffer_dmat, /*flags*/0, 941 &next_ccb->dmamap); 942 if (error != 0) 943 break; 944 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, next_ccb, links); 945 segs += BT_NSEG; 946 physaddr += (BT_NSEG * sizeof(bt_sg_t)); 947 next_ccb++; 948 bt->num_ccbs++; 949 } 950 951 /* Reserve a CCB for error recovery */ 952 if (bt->recovery_bccb == NULL) { 953 bt->recovery_bccb = SLIST_FIRST(&bt->free_bt_ccbs); 954 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links); 955 } 956} 957 958static __inline void 959btfreeccb(struct bt_softc *bt, struct bt_ccb *bccb) 960{ 961 int s; 962 963 s = splcam(); 964 if ((bccb->flags & BCCB_ACTIVE) != 0) 965 LIST_REMOVE(&bccb->ccb->ccb_h, sim_links.le); 966 if (bt->resource_shortage != 0 967 && (bccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 968 bccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 969 bt->resource_shortage = FALSE; 970 } 971 bccb->flags = BCCB_FREE; 972 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, bccb, links);
|
| 973 bt->active_ccbs--;
|
927 splx(s); 928} 929 930static __inline struct bt_ccb* 931btgetccb(struct bt_softc *bt) 932{ 933 struct bt_ccb* bccb; 934 int s; 935 936 s = splcam(); 937 if ((bccb = SLIST_FIRST(&bt->free_bt_ccbs)) != NULL) { 938 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
| 974 splx(s); 975} 976 977static __inline struct bt_ccb* 978btgetccb(struct bt_softc *bt) 979{ 980 struct bt_ccb* bccb; 981 int s; 982 983 s = splcam(); 984 if ((bccb = SLIST_FIRST(&bt->free_bt_ccbs)) != NULL) { 985 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
|
| 986 bt->active_ccbs++;
|
939 } else if (bt->num_ccbs < bt->max_ccbs) { 940 btallocccbs(bt); 941 bccb = SLIST_FIRST(&bt->free_bt_ccbs); 942 if (bccb == NULL) 943 printf("%s: Can't malloc BCCB\n", bt_name(bt));
| 987 } else if (bt->num_ccbs < bt->max_ccbs) { 988 btallocccbs(bt); 989 bccb = SLIST_FIRST(&bt->free_bt_ccbs); 990 if (bccb == NULL) 991 printf("%s: Can't malloc BCCB\n", bt_name(bt));
|
944 else
| 992 else {
|
945 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
| 993 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
|
| 994 bt->active_ccbs++; 995 }
|
946 } 947 splx(s); 948 949 return (bccb); 950} 951 952static void 953btaction(struct cam_sim *sim, union ccb *ccb) 954{ 955 struct bt_softc *bt; 956 957 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("btaction\n")); 958 959 bt = (struct bt_softc *)cam_sim_softc(sim); 960 961 switch (ccb->ccb_h.func_code) { 962 /* Common cases first */ 963 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 964 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 965 { 966 struct bt_ccb *bccb; 967 struct bt_hccb *hccb; 968 u_int16_t targ_mask; 969 970 /* 971 * get a bccb to use. 972 */ 973 if ((bccb = btgetccb(bt)) == NULL) { 974 int s; 975 976 s = splcam(); 977 bt->resource_shortage = TRUE; 978 splx(s); 979 xpt_freeze_simq(bt->sim, /*count*/1); 980 ccb->ccb_h.status = CAM_REQUEUE_REQ; 981 xpt_done(ccb); 982 return; 983 } 984 985 hccb = &bccb->hccb; 986 987 /* 988 * So we can find the BCCB when an abort is requested 989 */ 990 bccb->ccb = ccb; 991 ccb->ccb_h.ccb_bccb_ptr = bccb; 992 ccb->ccb_h.ccb_bt_ptr = bt; 993 994 /* 995 * Put all the arguments for the xfer in the bccb 996 */ 997 hccb->target_id = ccb->ccb_h.target_id; 998 hccb->target_lun = ccb->ccb_h.target_lun; 999 hccb->btstat = 0; 1000 hccb->sdstat = 0; 1001 targ_mask = (0x01 << hccb->target_id); 1002 1003 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1004 struct ccb_scsiio *csio; 1005 struct ccb_hdr *ccbh; 1006 1007 csio = &ccb->csio; 1008 ccbh = &csio->ccb_h; 1009 hccb->opcode = INITIATOR_CCB_WRESID; 1010 hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0; 1011 hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0; 1012 hccb->cmd_len = csio->cdb_len; 1013 if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) { 1014 ccb->ccb_h.status = CAM_REQ_INVALID; 1015 btfreeccb(bt, bccb); 1016 xpt_done(ccb); 1017 return; 1018 } 1019 hccb->sense_len = csio->sense_len; 1020 if ((ccbh->flags & CAM_TAG_ACTION_VALID) != 0 1021 && ccb->csio.tag_action != CAM_TAG_ACTION_NONE) { 1022 hccb->tag_enable = TRUE; 1023 hccb->tag_type = (ccb->csio.tag_action & 0x3); 1024 } else { 1025 hccb->tag_enable = FALSE; 1026 hccb->tag_type = 0; 1027 } 1028 if ((ccbh->flags & CAM_CDB_POINTER) != 0) { 1029 if ((ccbh->flags & CAM_CDB_PHYS) == 0) { 1030 bcopy(csio->cdb_io.cdb_ptr, 1031 hccb->scsi_cdb, hccb->cmd_len); 1032 } else { 1033 /* I guess I could map it in... */ 1034 ccbh->status = CAM_REQ_INVALID; 1035 btfreeccb(bt, bccb); 1036 xpt_done(ccb); 1037 return; 1038 } 1039 } else { 1040 bcopy(csio->cdb_io.cdb_bytes, 1041 hccb->scsi_cdb, hccb->cmd_len); 1042 } 1043 /* If need be, bounce our sense buffer */ 1044 if (bt->sense_buffers != NULL) { 1045 hccb->sense_addr = btsensepaddr(bt, bccb); 1046 } else { 1047 hccb->sense_addr = vtophys(&csio->sense_data); 1048 } 1049 /* 1050 * If we have any data to send with this command, 1051 * map it into bus space. 1052 */ 1053 /* Only use S/G if there is a transfer */ 1054 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1055 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 1056 /* 1057 * We've been given a pointer 1058 * to a single buffer. 1059 */ 1060 if ((ccbh->flags & CAM_DATA_PHYS)==0) { 1061 int s; 1062 int error; 1063 1064 s = splsoftvm(); 1065 error = bus_dmamap_load( 1066 bt->buffer_dmat, 1067 bccb->dmamap, 1068 csio->data_ptr, 1069 csio->dxfer_len, 1070 btexecuteccb, 1071 bccb, 1072 /*flags*/0); 1073 if (error == EINPROGRESS) { 1074 /* 1075 * So as to maintain 1076 * ordering, freeze the 1077 * controller queue 1078 * until our mapping is 1079 * returned. 1080 */ 1081 xpt_freeze_simq(bt->sim, 1082 1); 1083 csio->ccb_h.status |= 1084 CAM_RELEASE_SIMQ; 1085 } 1086 splx(s); 1087 } else { 1088 struct bus_dma_segment seg; 1089 1090 /* Pointer to physical buffer */ 1091 seg.ds_addr = 1092 (bus_addr_t)csio->data_ptr; 1093 seg.ds_len = csio->dxfer_len; 1094 btexecuteccb(bccb, &seg, 1, 0); 1095 } 1096 } else { 1097 struct bus_dma_segment *segs; 1098 1099 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 1100 panic("btaction - Physical " 1101 "segment pointers " 1102 "unsupported"); 1103 1104 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 1105 panic("btaction - Virtual " 1106 "segment addresses " 1107 "unsupported"); 1108 1109 /* Just use the segments provided */ 1110 segs = (struct bus_dma_segment *) 1111 csio->data_ptr; 1112 btexecuteccb(bccb, segs, 1113 csio->sglist_cnt, 0); 1114 } 1115 } else { 1116 btexecuteccb(bccb, NULL, 0, 0); 1117 } 1118 } else { 1119 hccb->opcode = INITIATOR_BUS_DEV_RESET; 1120 /* No data transfer */ 1121 hccb->datain = TRUE; 1122 hccb->dataout = TRUE; 1123 hccb->cmd_len = 0; 1124 hccb->sense_len = 0; 1125 hccb->tag_enable = FALSE; 1126 hccb->tag_type = 0; 1127 btexecuteccb(bccb, NULL, 0, 0); 1128 } 1129 break; 1130 } 1131 case XPT_EN_LUN: /* Enable LUN as a target */ 1132 case XPT_TARGET_IO: /* Execute target I/O request */ 1133 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1134 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1135 case XPT_ABORT: /* Abort the specified CCB */ 1136 /* XXX Implement */ 1137 ccb->ccb_h.status = CAM_REQ_INVALID; 1138 xpt_done(ccb); 1139 break; 1140 case XPT_SET_TRAN_SETTINGS: 1141 { 1142 /* XXX Implement */ 1143 ccb->ccb_h.status = CAM_REQ_CMP; 1144 xpt_done(ccb); 1145 break; 1146 } 1147 case XPT_GET_TRAN_SETTINGS: 1148 /* Get default/user set transfer settings for the target */ 1149 { 1150 struct ccb_trans_settings *cts; 1151 u_int target_mask; 1152 1153 cts = &ccb->cts; 1154 target_mask = 0x01 << ccb->ccb_h.target_id; 1155 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1156 cts->flags = 0; 1157 if ((bt->disc_permitted & target_mask) != 0) 1158 cts->flags |= CCB_TRANS_DISC_ENB; 1159 if ((bt->tags_permitted & target_mask) != 0) 1160 cts->flags |= CCB_TRANS_TAG_ENB; 1161 if ((bt->wide_permitted & target_mask) != 0) 1162 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1163 else 1164 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1165 if ((bt->ultra_permitted & target_mask) != 0) 1166 cts->sync_period = 12; 1167 else if ((bt->fast_permitted & target_mask) != 0) 1168 cts->sync_period = 25; 1169 else if ((bt->sync_permitted & target_mask) != 0) 1170 cts->sync_period = 50; 1171 else 1172 cts->sync_period = 0; 1173 1174 if (cts->sync_period != 0) 1175 cts->sync_offset = 15; 1176 1177 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1178 | CCB_TRANS_SYNC_OFFSET_VALID 1179 | CCB_TRANS_BUS_WIDTH_VALID 1180 | CCB_TRANS_DISC_VALID 1181 | CCB_TRANS_TQ_VALID; 1182 } else { 1183 btfetchtransinfo(bt, cts); 1184 } 1185 1186 ccb->ccb_h.status = CAM_REQ_CMP; 1187 xpt_done(ccb); 1188 break; 1189 } 1190 case XPT_CALC_GEOMETRY: 1191 { 1192 struct ccb_calc_geometry *ccg; 1193 u_int32_t size_mb; 1194 u_int32_t secs_per_cylinder; 1195 1196 ccg = &ccb->ccg; 1197 size_mb = ccg->volume_size 1198 / ((1024L * 1024L) / ccg->block_size); 1199 1200 if (size_mb >= 1024 && (bt->extended_trans != 0)) { 1201 if (size_mb >= 2048) { 1202 ccg->heads = 255; 1203 ccg->secs_per_track = 63; 1204 } else { 1205 ccg->heads = 128; 1206 ccg->secs_per_track = 32; 1207 } 1208 } else { 1209 ccg->heads = 64; 1210 ccg->secs_per_track = 32; 1211 } 1212 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1213 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1214 ccb->ccb_h.status = CAM_REQ_CMP; 1215 xpt_done(ccb); 1216 break; 1217 } 1218 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1219 { 1220 btreset(bt, /*hardreset*/TRUE); 1221 ccb->ccb_h.status = CAM_REQ_CMP; 1222 xpt_done(ccb); 1223 break; 1224 } 1225 case XPT_TERM_IO: /* Terminate the I/O process */ 1226 /* XXX Implement */ 1227 ccb->ccb_h.status = CAM_REQ_INVALID; 1228 xpt_done(ccb); 1229 break; 1230 case XPT_PATH_INQ: /* Path routing inquiry */ 1231 { 1232 struct ccb_pathinq *cpi = &ccb->cpi; 1233 1234 cpi->version_num = 1; /* XXX??? */ 1235 cpi->hba_inquiry = PI_SDTR_ABLE; 1236 if (bt->tag_capable != 0) 1237 cpi->hba_inquiry |= PI_TAG_ABLE; 1238 if (bt->wide_bus != 0) 1239 cpi->hba_inquiry |= PI_WIDE_16; 1240 cpi->target_sprt = 0; 1241 cpi->hba_misc = 0; 1242 cpi->hba_eng_cnt = 0; 1243 cpi->max_target = bt->wide_bus ? 15 : 7; 1244 cpi->max_lun = 7; 1245 cpi->initiator_id = bt->scsi_id; 1246 cpi->bus_id = cam_sim_bus(sim); 1247 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1248 strncpy(cpi->hba_vid, "BusLogic", HBA_IDLEN); 1249 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1250 cpi->unit_number = cam_sim_unit(sim); 1251 cpi->ccb_h.status = CAM_REQ_CMP; 1252 xpt_done(ccb); 1253 break; 1254 } 1255 default: 1256 ccb->ccb_h.status = CAM_REQ_INVALID; 1257 xpt_done(ccb); 1258 break; 1259 } 1260} 1261 1262static void 1263btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1264{ 1265 struct bt_ccb *bccb; 1266 union ccb *ccb; 1267 struct bt_softc *bt; 1268 int s; 1269 1270 bccb = (struct bt_ccb *)arg; 1271 ccb = bccb->ccb; 1272 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 1273 1274 if (error != 0) { 1275 if (error != EFBIG) 1276 printf("%s: Unexepected error 0x%x returned from " 1277 "bus_dmamap_load\n", bt_name(bt), error); 1278 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 1279 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1280 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 1281 } 1282 btfreeccb(bt, bccb); 1283 xpt_done(ccb); 1284 return; 1285 } 1286 1287 if (nseg != 0) { 1288 bt_sg_t *sg; 1289 bus_dma_segment_t *end_seg; 1290 bus_dmasync_op_t op; 1291 1292 end_seg = dm_segs + nseg; 1293 1294 /* Copy the segments into our SG list */ 1295 sg = bccb->sg_list; 1296 while (dm_segs < end_seg) { 1297 sg->len = dm_segs->ds_len; 1298 sg->addr = dm_segs->ds_addr; 1299 sg++; 1300 dm_segs++; 1301 } 1302 1303 if (nseg > 1) { 1304 bccb->hccb.opcode = INITIATOR_SG_CCB_WRESID; 1305 bccb->hccb.data_len = sizeof(bt_sg_t) * nseg; 1306 bccb->hccb.data_addr = bccb->sg_list_phys; 1307 } else { 1308 bccb->hccb.data_len = bccb->sg_list->len; 1309 bccb->hccb.data_addr = bccb->sg_list->addr; 1310 } 1311 1312 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1313 op = BUS_DMASYNC_PREREAD; 1314 else 1315 op = BUS_DMASYNC_PREWRITE; 1316 1317 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1318 1319 } else { 1320 bccb->hccb.opcode = INITIATOR_SG_CCB; 1321 bccb->hccb.data_len = 0; 1322 bccb->hccb.data_addr = 0; 1323 } 1324 1325 s = splcam(); 1326 1327 /* 1328 * Last time we need to check if this CCB needs to 1329 * be aborted. 1330 */ 1331 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1332 if (nseg != 0) 1333 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1334 btfreeccb(bt, bccb); 1335 xpt_done(ccb); 1336 splx(s); 1337 return; 1338 } 1339 1340 bccb->flags = BCCB_ACTIVE; 1341 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1342 LIST_INSERT_HEAD(&bt->pending_ccbs, &ccb->ccb_h, sim_links.le); 1343 1344 ccb->ccb_h.timeout_ch = 1345 timeout(bttimeout, (caddr_t)bccb, 1346 (ccb->ccb_h.timeout * hz) / 1000); 1347 1348 /* Tell the adapter about this command */ 1349 bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb);
| 996 } 997 splx(s); 998 999 return (bccb); 1000} 1001 1002static void 1003btaction(struct cam_sim *sim, union ccb *ccb) 1004{ 1005 struct bt_softc *bt; 1006 1007 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("btaction\n")); 1008 1009 bt = (struct bt_softc *)cam_sim_softc(sim); 1010 1011 switch (ccb->ccb_h.func_code) { 1012 /* Common cases first */ 1013 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 1014 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 1015 { 1016 struct bt_ccb *bccb; 1017 struct bt_hccb *hccb; 1018 u_int16_t targ_mask; 1019 1020 /* 1021 * get a bccb to use. 1022 */ 1023 if ((bccb = btgetccb(bt)) == NULL) { 1024 int s; 1025 1026 s = splcam(); 1027 bt->resource_shortage = TRUE; 1028 splx(s); 1029 xpt_freeze_simq(bt->sim, /*count*/1); 1030 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1031 xpt_done(ccb); 1032 return; 1033 } 1034 1035 hccb = &bccb->hccb; 1036 1037 /* 1038 * So we can find the BCCB when an abort is requested 1039 */ 1040 bccb->ccb = ccb; 1041 ccb->ccb_h.ccb_bccb_ptr = bccb; 1042 ccb->ccb_h.ccb_bt_ptr = bt; 1043 1044 /* 1045 * Put all the arguments for the xfer in the bccb 1046 */ 1047 hccb->target_id = ccb->ccb_h.target_id; 1048 hccb->target_lun = ccb->ccb_h.target_lun; 1049 hccb->btstat = 0; 1050 hccb->sdstat = 0; 1051 targ_mask = (0x01 << hccb->target_id); 1052 1053 if (ccb->ccb_h.func_code == XPT_SCSI_IO) { 1054 struct ccb_scsiio *csio; 1055 struct ccb_hdr *ccbh; 1056 1057 csio = &ccb->csio; 1058 ccbh = &csio->ccb_h; 1059 hccb->opcode = INITIATOR_CCB_WRESID; 1060 hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0; 1061 hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0; 1062 hccb->cmd_len = csio->cdb_len; 1063 if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) { 1064 ccb->ccb_h.status = CAM_REQ_INVALID; 1065 btfreeccb(bt, bccb); 1066 xpt_done(ccb); 1067 return; 1068 } 1069 hccb->sense_len = csio->sense_len; 1070 if ((ccbh->flags & CAM_TAG_ACTION_VALID) != 0 1071 && ccb->csio.tag_action != CAM_TAG_ACTION_NONE) { 1072 hccb->tag_enable = TRUE; 1073 hccb->tag_type = (ccb->csio.tag_action & 0x3); 1074 } else { 1075 hccb->tag_enable = FALSE; 1076 hccb->tag_type = 0; 1077 } 1078 if ((ccbh->flags & CAM_CDB_POINTER) != 0) { 1079 if ((ccbh->flags & CAM_CDB_PHYS) == 0) { 1080 bcopy(csio->cdb_io.cdb_ptr, 1081 hccb->scsi_cdb, hccb->cmd_len); 1082 } else { 1083 /* I guess I could map it in... */ 1084 ccbh->status = CAM_REQ_INVALID; 1085 btfreeccb(bt, bccb); 1086 xpt_done(ccb); 1087 return; 1088 } 1089 } else { 1090 bcopy(csio->cdb_io.cdb_bytes, 1091 hccb->scsi_cdb, hccb->cmd_len); 1092 } 1093 /* If need be, bounce our sense buffer */ 1094 if (bt->sense_buffers != NULL) { 1095 hccb->sense_addr = btsensepaddr(bt, bccb); 1096 } else { 1097 hccb->sense_addr = vtophys(&csio->sense_data); 1098 } 1099 /* 1100 * If we have any data to send with this command, 1101 * map it into bus space. 1102 */ 1103 /* Only use S/G if there is a transfer */ 1104 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1105 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 1106 /* 1107 * We've been given a pointer 1108 * to a single buffer. 1109 */ 1110 if ((ccbh->flags & CAM_DATA_PHYS)==0) { 1111 int s; 1112 int error; 1113 1114 s = splsoftvm(); 1115 error = bus_dmamap_load( 1116 bt->buffer_dmat, 1117 bccb->dmamap, 1118 csio->data_ptr, 1119 csio->dxfer_len, 1120 btexecuteccb, 1121 bccb, 1122 /*flags*/0); 1123 if (error == EINPROGRESS) { 1124 /* 1125 * So as to maintain 1126 * ordering, freeze the 1127 * controller queue 1128 * until our mapping is 1129 * returned. 1130 */ 1131 xpt_freeze_simq(bt->sim, 1132 1); 1133 csio->ccb_h.status |= 1134 CAM_RELEASE_SIMQ; 1135 } 1136 splx(s); 1137 } else { 1138 struct bus_dma_segment seg; 1139 1140 /* Pointer to physical buffer */ 1141 seg.ds_addr = 1142 (bus_addr_t)csio->data_ptr; 1143 seg.ds_len = csio->dxfer_len; 1144 btexecuteccb(bccb, &seg, 1, 0); 1145 } 1146 } else { 1147 struct bus_dma_segment *segs; 1148 1149 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 1150 panic("btaction - Physical " 1151 "segment pointers " 1152 "unsupported"); 1153 1154 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 1155 panic("btaction - Virtual " 1156 "segment addresses " 1157 "unsupported"); 1158 1159 /* Just use the segments provided */ 1160 segs = (struct bus_dma_segment *) 1161 csio->data_ptr; 1162 btexecuteccb(bccb, segs, 1163 csio->sglist_cnt, 0); 1164 } 1165 } else { 1166 btexecuteccb(bccb, NULL, 0, 0); 1167 } 1168 } else { 1169 hccb->opcode = INITIATOR_BUS_DEV_RESET; 1170 /* No data transfer */ 1171 hccb->datain = TRUE; 1172 hccb->dataout = TRUE; 1173 hccb->cmd_len = 0; 1174 hccb->sense_len = 0; 1175 hccb->tag_enable = FALSE; 1176 hccb->tag_type = 0; 1177 btexecuteccb(bccb, NULL, 0, 0); 1178 } 1179 break; 1180 } 1181 case XPT_EN_LUN: /* Enable LUN as a target */ 1182 case XPT_TARGET_IO: /* Execute target I/O request */ 1183 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 1184 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 1185 case XPT_ABORT: /* Abort the specified CCB */ 1186 /* XXX Implement */ 1187 ccb->ccb_h.status = CAM_REQ_INVALID; 1188 xpt_done(ccb); 1189 break; 1190 case XPT_SET_TRAN_SETTINGS: 1191 { 1192 /* XXX Implement */ 1193 ccb->ccb_h.status = CAM_REQ_CMP; 1194 xpt_done(ccb); 1195 break; 1196 } 1197 case XPT_GET_TRAN_SETTINGS: 1198 /* Get default/user set transfer settings for the target */ 1199 { 1200 struct ccb_trans_settings *cts; 1201 u_int target_mask; 1202 1203 cts = &ccb->cts; 1204 target_mask = 0x01 << ccb->ccb_h.target_id; 1205 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1206 cts->flags = 0; 1207 if ((bt->disc_permitted & target_mask) != 0) 1208 cts->flags |= CCB_TRANS_DISC_ENB; 1209 if ((bt->tags_permitted & target_mask) != 0) 1210 cts->flags |= CCB_TRANS_TAG_ENB; 1211 if ((bt->wide_permitted & target_mask) != 0) 1212 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1213 else 1214 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1215 if ((bt->ultra_permitted & target_mask) != 0) 1216 cts->sync_period = 12; 1217 else if ((bt->fast_permitted & target_mask) != 0) 1218 cts->sync_period = 25; 1219 else if ((bt->sync_permitted & target_mask) != 0) 1220 cts->sync_period = 50; 1221 else 1222 cts->sync_period = 0; 1223 1224 if (cts->sync_period != 0) 1225 cts->sync_offset = 15; 1226 1227 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1228 | CCB_TRANS_SYNC_OFFSET_VALID 1229 | CCB_TRANS_BUS_WIDTH_VALID 1230 | CCB_TRANS_DISC_VALID 1231 | CCB_TRANS_TQ_VALID; 1232 } else { 1233 btfetchtransinfo(bt, cts); 1234 } 1235 1236 ccb->ccb_h.status = CAM_REQ_CMP; 1237 xpt_done(ccb); 1238 break; 1239 } 1240 case XPT_CALC_GEOMETRY: 1241 { 1242 struct ccb_calc_geometry *ccg; 1243 u_int32_t size_mb; 1244 u_int32_t secs_per_cylinder; 1245 1246 ccg = &ccb->ccg; 1247 size_mb = ccg->volume_size 1248 / ((1024L * 1024L) / ccg->block_size); 1249 1250 if (size_mb >= 1024 && (bt->extended_trans != 0)) { 1251 if (size_mb >= 2048) { 1252 ccg->heads = 255; 1253 ccg->secs_per_track = 63; 1254 } else { 1255 ccg->heads = 128; 1256 ccg->secs_per_track = 32; 1257 } 1258 } else { 1259 ccg->heads = 64; 1260 ccg->secs_per_track = 32; 1261 } 1262 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1263 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1264 ccb->ccb_h.status = CAM_REQ_CMP; 1265 xpt_done(ccb); 1266 break; 1267 } 1268 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1269 { 1270 btreset(bt, /*hardreset*/TRUE); 1271 ccb->ccb_h.status = CAM_REQ_CMP; 1272 xpt_done(ccb); 1273 break; 1274 } 1275 case XPT_TERM_IO: /* Terminate the I/O process */ 1276 /* XXX Implement */ 1277 ccb->ccb_h.status = CAM_REQ_INVALID; 1278 xpt_done(ccb); 1279 break; 1280 case XPT_PATH_INQ: /* Path routing inquiry */ 1281 { 1282 struct ccb_pathinq *cpi = &ccb->cpi; 1283 1284 cpi->version_num = 1; /* XXX??? */ 1285 cpi->hba_inquiry = PI_SDTR_ABLE; 1286 if (bt->tag_capable != 0) 1287 cpi->hba_inquiry |= PI_TAG_ABLE; 1288 if (bt->wide_bus != 0) 1289 cpi->hba_inquiry |= PI_WIDE_16; 1290 cpi->target_sprt = 0; 1291 cpi->hba_misc = 0; 1292 cpi->hba_eng_cnt = 0; 1293 cpi->max_target = bt->wide_bus ? 15 : 7; 1294 cpi->max_lun = 7; 1295 cpi->initiator_id = bt->scsi_id; 1296 cpi->bus_id = cam_sim_bus(sim); 1297 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1298 strncpy(cpi->hba_vid, "BusLogic", HBA_IDLEN); 1299 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1300 cpi->unit_number = cam_sim_unit(sim); 1301 cpi->ccb_h.status = CAM_REQ_CMP; 1302 xpt_done(ccb); 1303 break; 1304 } 1305 default: 1306 ccb->ccb_h.status = CAM_REQ_INVALID; 1307 xpt_done(ccb); 1308 break; 1309 } 1310} 1311 1312static void 1313btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 1314{ 1315 struct bt_ccb *bccb; 1316 union ccb *ccb; 1317 struct bt_softc *bt; 1318 int s; 1319 1320 bccb = (struct bt_ccb *)arg; 1321 ccb = bccb->ccb; 1322 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 1323 1324 if (error != 0) { 1325 if (error != EFBIG) 1326 printf("%s: Unexepected error 0x%x returned from " 1327 "bus_dmamap_load\n", bt_name(bt), error); 1328 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 1329 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 1330 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 1331 } 1332 btfreeccb(bt, bccb); 1333 xpt_done(ccb); 1334 return; 1335 } 1336 1337 if (nseg != 0) { 1338 bt_sg_t *sg; 1339 bus_dma_segment_t *end_seg; 1340 bus_dmasync_op_t op; 1341 1342 end_seg = dm_segs + nseg; 1343 1344 /* Copy the segments into our SG list */ 1345 sg = bccb->sg_list; 1346 while (dm_segs < end_seg) { 1347 sg->len = dm_segs->ds_len; 1348 sg->addr = dm_segs->ds_addr; 1349 sg++; 1350 dm_segs++; 1351 } 1352 1353 if (nseg > 1) { 1354 bccb->hccb.opcode = INITIATOR_SG_CCB_WRESID; 1355 bccb->hccb.data_len = sizeof(bt_sg_t) * nseg; 1356 bccb->hccb.data_addr = bccb->sg_list_phys; 1357 } else { 1358 bccb->hccb.data_len = bccb->sg_list->len; 1359 bccb->hccb.data_addr = bccb->sg_list->addr; 1360 } 1361 1362 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1363 op = BUS_DMASYNC_PREREAD; 1364 else 1365 op = BUS_DMASYNC_PREWRITE; 1366 1367 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1368 1369 } else { 1370 bccb->hccb.opcode = INITIATOR_SG_CCB; 1371 bccb->hccb.data_len = 0; 1372 bccb->hccb.data_addr = 0; 1373 } 1374 1375 s = splcam(); 1376 1377 /* 1378 * Last time we need to check if this CCB needs to 1379 * be aborted. 1380 */ 1381 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1382 if (nseg != 0) 1383 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1384 btfreeccb(bt, bccb); 1385 xpt_done(ccb); 1386 splx(s); 1387 return; 1388 } 1389 1390 bccb->flags = BCCB_ACTIVE; 1391 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1392 LIST_INSERT_HEAD(&bt->pending_ccbs, &ccb->ccb_h, sim_links.le); 1393 1394 ccb->ccb_h.timeout_ch = 1395 timeout(bttimeout, (caddr_t)bccb, 1396 (ccb->ccb_h.timeout * hz) / 1000); 1397 1398 /* Tell the adapter about this command */ 1399 bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb);
|
1350 if (bt->cur_outbox->action_code != BMBO_FREE) 1351 panic("%s: Too few mailboxes or to many ccbs???", bt_name(bt));
| 1400 if (bt->cur_outbox->action_code != BMBO_FREE) { 1401 /* 1402 * We should never encounter a busy mailbox. 1403 * If we do, warn the user, and treat it as 1404 * a resource shortage. If the controller is 1405 * hung, one of the pending transactions will 1406 * timeout causing us to start recovery operations. 1407 */ 1408 printf("%s: Encountered busy mailbox with %d out of %d " 1409 "commands active!!!", bt_name(bt), bt->active_ccbs, 1410 bt->max_ccbs); 1411 untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch); 1412 if (nseg != 0) 1413 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1414 btfreeccb(bt, bccb); 1415 bt->resource_shortage = TRUE; 1416 xpt_freeze_simq(bt->sim, /*count*/1); 1417 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1418 xpt_done(ccb); 1419 return; 1420 }
|
1352 bt->cur_outbox->action_code = BMBO_START; 1353 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 1354 btnextoutbox(bt); 1355 splx(s); 1356} 1357 1358void 1359bt_intr(void *arg) 1360{ 1361 struct bt_softc *bt; 1362 u_int intstat; 1363 1364 bt = (struct bt_softc *)arg; 1365 while (((intstat = bt_inb(bt, INTSTAT_REG)) & INTR_PENDING) != 0) { 1366 1367 if ((intstat & CMD_COMPLETE) != 0) { 1368 bt->latched_status = bt_inb(bt, STATUS_REG); 1369 bt->command_cmp = TRUE; 1370 } 1371 1372 bt_outb(bt, CONTROL_REG, RESET_INTR); 1373 1374 if ((intstat & IMB_LOADED) != 0) { 1375 while (bt->cur_inbox->comp_code != BMBI_FREE) { 1376 btdone(bt, 1377 btccbptov(bt, bt->cur_inbox->ccb_addr), 1378 bt->cur_inbox->comp_code); 1379 bt->cur_inbox->comp_code = BMBI_FREE; 1380 btnextinbox(bt); 1381 } 1382 } 1383 1384 if ((intstat & SCSI_BUS_RESET) != 0) { 1385 btreset(bt, /*hardreset*/FALSE); 1386 } 1387 } 1388} 1389 1390static void 1391btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code) 1392{ 1393 union ccb *ccb; 1394 struct ccb_scsiio *csio; 1395 1396 ccb = bccb->ccb; 1397 csio = &bccb->ccb->csio; 1398 1399 if ((bccb->flags & BCCB_ACTIVE) == 0) { 1400 printf("%s: btdone - Attempt to free non-active BCCB %p\n", 1401 bt_name(bt), (void *)bccb); 1402 return; 1403 } 1404 1405 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1406 bus_dmasync_op_t op; 1407 1408 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1409 op = BUS_DMASYNC_POSTREAD; 1410 else 1411 op = BUS_DMASYNC_POSTWRITE; 1412 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1413 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1414 } 1415 1416 if (bccb == bt->recovery_bccb) { 1417 /* 1418 * The recovery BCCB does not have a CCB associated 1419 * with it, so short circuit the normal error handling. 1420 * We now traverse our list of pending CCBs and process 1421 * any that were terminated by the recovery CCBs action. 1422 * We also reinstate timeouts for all remaining, pending, 1423 * CCBs. 1424 */ 1425 struct cam_path *path; 1426 struct ccb_hdr *ccb_h; 1427 cam_status error; 1428 1429 /* Notify all clients that a BDR occured */ 1430 error = xpt_create_path(&path, /*periph*/NULL, 1431 cam_sim_path(bt->sim), 1432 bccb->hccb.target_id, 1433 CAM_LUN_WILDCARD); 1434 1435 if (error == CAM_REQ_CMP) 1436 xpt_async(AC_SENT_BDR, path, NULL); 1437 1438 ccb_h = LIST_FIRST(&bt->pending_ccbs); 1439 while (ccb_h != NULL) { 1440 struct bt_ccb *pending_bccb; 1441 1442 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1443 if (pending_bccb->hccb.target_id 1444 == bccb->hccb.target_id) { 1445 pending_bccb->hccb.btstat = BTSTAT_HA_BDR; 1446 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1447 btdone(bt, pending_bccb, BMBI_ERROR); 1448 } else { 1449 ccb_h->timeout_ch = 1450 timeout(bttimeout, (caddr_t)pending_bccb, 1451 (ccb_h->timeout * hz) / 1000); 1452 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1453 } 1454 } 1455 printf("%s: No longer in timeout\n", bt_name(bt)); 1456 return; 1457 } 1458 1459 untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch); 1460 1461 switch (comp_code) { 1462 case BMBI_FREE: 1463 printf("%s: btdone - CCB completed with free status!\n", 1464 bt_name(bt)); 1465 break; 1466 case BMBI_NOT_FOUND: 1467 printf("%s: btdone - CCB Abort failed to find CCB\n", 1468 bt_name(bt)); 1469 break; 1470 case BMBI_ABORT: 1471 case BMBI_ERROR:
| 1421 bt->cur_outbox->action_code = BMBO_START; 1422 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 1423 btnextoutbox(bt); 1424 splx(s); 1425} 1426 1427void 1428bt_intr(void *arg) 1429{ 1430 struct bt_softc *bt; 1431 u_int intstat; 1432 1433 bt = (struct bt_softc *)arg; 1434 while (((intstat = bt_inb(bt, INTSTAT_REG)) & INTR_PENDING) != 0) { 1435 1436 if ((intstat & CMD_COMPLETE) != 0) { 1437 bt->latched_status = bt_inb(bt, STATUS_REG); 1438 bt->command_cmp = TRUE; 1439 } 1440 1441 bt_outb(bt, CONTROL_REG, RESET_INTR); 1442 1443 if ((intstat & IMB_LOADED) != 0) { 1444 while (bt->cur_inbox->comp_code != BMBI_FREE) { 1445 btdone(bt, 1446 btccbptov(bt, bt->cur_inbox->ccb_addr), 1447 bt->cur_inbox->comp_code); 1448 bt->cur_inbox->comp_code = BMBI_FREE; 1449 btnextinbox(bt); 1450 } 1451 } 1452 1453 if ((intstat & SCSI_BUS_RESET) != 0) { 1454 btreset(bt, /*hardreset*/FALSE); 1455 } 1456 } 1457} 1458 1459static void 1460btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code) 1461{ 1462 union ccb *ccb; 1463 struct ccb_scsiio *csio; 1464 1465 ccb = bccb->ccb; 1466 csio = &bccb->ccb->csio; 1467 1468 if ((bccb->flags & BCCB_ACTIVE) == 0) { 1469 printf("%s: btdone - Attempt to free non-active BCCB %p\n", 1470 bt_name(bt), (void *)bccb); 1471 return; 1472 } 1473 1474 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1475 bus_dmasync_op_t op; 1476 1477 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1478 op = BUS_DMASYNC_POSTREAD; 1479 else 1480 op = BUS_DMASYNC_POSTWRITE; 1481 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op); 1482 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap); 1483 } 1484 1485 if (bccb == bt->recovery_bccb) { 1486 /* 1487 * The recovery BCCB does not have a CCB associated 1488 * with it, so short circuit the normal error handling. 1489 * We now traverse our list of pending CCBs and process 1490 * any that were terminated by the recovery CCBs action. 1491 * We also reinstate timeouts for all remaining, pending, 1492 * CCBs. 1493 */ 1494 struct cam_path *path; 1495 struct ccb_hdr *ccb_h; 1496 cam_status error; 1497 1498 /* Notify all clients that a BDR occured */ 1499 error = xpt_create_path(&path, /*periph*/NULL, 1500 cam_sim_path(bt->sim), 1501 bccb->hccb.target_id, 1502 CAM_LUN_WILDCARD); 1503 1504 if (error == CAM_REQ_CMP) 1505 xpt_async(AC_SENT_BDR, path, NULL); 1506 1507 ccb_h = LIST_FIRST(&bt->pending_ccbs); 1508 while (ccb_h != NULL) { 1509 struct bt_ccb *pending_bccb; 1510 1511 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1512 if (pending_bccb->hccb.target_id 1513 == bccb->hccb.target_id) { 1514 pending_bccb->hccb.btstat = BTSTAT_HA_BDR; 1515 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1516 btdone(bt, pending_bccb, BMBI_ERROR); 1517 } else { 1518 ccb_h->timeout_ch = 1519 timeout(bttimeout, (caddr_t)pending_bccb, 1520 (ccb_h->timeout * hz) / 1000); 1521 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 1522 } 1523 } 1524 printf("%s: No longer in timeout\n", bt_name(bt)); 1525 return; 1526 } 1527 1528 untimeout(bttimeout, bccb, ccb->ccb_h.timeout_ch); 1529 1530 switch (comp_code) { 1531 case BMBI_FREE: 1532 printf("%s: btdone - CCB completed with free status!\n", 1533 bt_name(bt)); 1534 break; 1535 case BMBI_NOT_FOUND: 1536 printf("%s: btdone - CCB Abort failed to find CCB\n", 1537 bt_name(bt)); 1538 break; 1539 case BMBI_ABORT: 1540 case BMBI_ERROR:
|
1472#if 0 1473 printf("bt: ccb %x - error %x occured. btstat = %x, sdstat = %x\n", 1474 bccb, comp_code, bccb->hccb.btstat, bccb->hccb.sdstat); 1475#endif
| 1541 printf("bt: ccb %p - error %x occured. " 1542 "btstat = %x, sdstat = %x\n", 1543 (void *)bccb, comp_code, bccb->hccb.btstat, 1544 bccb->hccb.sdstat);
|
1476 /* An error occured */ 1477 switch(bccb->hccb.btstat) { 1478 case BTSTAT_DATARUN_ERROR:
| 1545 /* An error occured */ 1546 switch(bccb->hccb.btstat) { 1547 case BTSTAT_DATARUN_ERROR:
|
1479 if (bccb->hccb.data_len <= 0) {
| 1548 if (bccb->hccb.data_len == 0) { 1549 /* 1550 * At least firmware 4.22, does this 1551 * for a QUEUE FULL condition. 1552 */ 1553 bccb->hccb.sdstat = SCSI_STATUS_QUEUE_FULL; 1554 } else if (bccb->hccb.data_len < 0) {
|
1480 csio->ccb_h.status = CAM_DATA_RUN_ERR; 1481 break; 1482 } 1483 /* FALLTHROUGH */ 1484 case BTSTAT_NOERROR: 1485 case BTSTAT_LINKED_CMD_COMPLETE: 1486 case BTSTAT_LINKED_CMD_FLAG_COMPLETE: 1487 case BTSTAT_DATAUNDERUN_ERROR: 1488 1489 csio->scsi_status = bccb->hccb.sdstat; 1490 csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1491 switch(csio->scsi_status) { 1492 case SCSI_STATUS_CHECK_COND: 1493 case SCSI_STATUS_CMD_TERMINATED: 1494 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 1495 /* Bounce sense back if necessary */ 1496 if (bt->sense_buffers != NULL) { 1497 csio->sense_data = 1498 *btsensevaddr(bt, bccb); 1499 } 1500 break; 1501 default: 1502 break; 1503 case SCSI_STATUS_OK: 1504 csio->ccb_h.status = CAM_REQ_CMP; 1505 break; 1506 } 1507 csio->resid = bccb->hccb.data_len; 1508 break; 1509 case BTSTAT_SELTIMEOUT: 1510 csio->ccb_h.status = CAM_SEL_TIMEOUT; 1511 break; 1512 case BTSTAT_UNEXPECTED_BUSFREE: 1513 csio->ccb_h.status = CAM_UNEXP_BUSFREE; 1514 break; 1515 case BTSTAT_INVALID_PHASE: 1516 csio->ccb_h.status = CAM_SEQUENCE_FAIL; 1517 break; 1518 case BTSTAT_INVALID_ACTION_CODE: 1519 panic("%s: Inavlid Action code", bt_name(bt)); 1520 break; 1521 case BTSTAT_INVALID_OPCODE: 1522 panic("%s: Inavlid CCB Opcode code", bt_name(bt)); 1523 break; 1524 case BTSTAT_LINKED_CCB_LUN_MISMATCH: 1525 /* We don't even support linked commands... */ 1526 panic("%s: Linked CCB Lun Mismatch", bt_name(bt)); 1527 break; 1528 case BTSTAT_INVALID_CCB_OR_SG_PARAM: 1529 panic("%s: Invalid CCB or SG list", bt_name(bt)); 1530 break; 1531 case BTSTAT_AUTOSENSE_FAILED: 1532 csio->ccb_h.status = CAM_AUTOSENSE_FAIL; 1533 break; 1534 case BTSTAT_TAGGED_MSG_REJECTED: 1535 { 1536 struct ccb_trans_settings neg; 1537 1538 xpt_print_path(csio->ccb_h.path); 1539 printf("refuses tagged commands. Performing " 1540 "non-tagged I/O\n"); 1541 neg.flags = 0; 1542 neg.valid = CCB_TRANS_TQ_VALID; 1543 xpt_setup_ccb(&neg.ccb_h, csio->ccb_h.path, 1544 /*priority*/1); 1545 xpt_async(AC_TRANSFER_NEG, csio->ccb_h.path, &neg); 1546 bt->tags_permitted &= ~(0x01 << csio->ccb_h.target_id); 1547 csio->ccb_h.status = CAM_MSG_REJECT_REC; 1548 break; 1549 } 1550 case BTSTAT_UNSUPPORTED_MSG_RECEIVED: 1551 /* 1552 * XXX You would think that this is 1553 * a recoverable error... Hmmm. 1554 */ 1555 csio->ccb_h.status = CAM_REQ_CMP_ERR; 1556 break; 1557 case BTSTAT_HA_SOFTWARE_ERROR: 1558 case BTSTAT_HA_WATCHDOG_ERROR: 1559 case BTSTAT_HARDWARE_FAILURE: 1560 /* Hardware reset ??? Can we recover ??? */ 1561 csio->ccb_h.status = CAM_NO_HBA; 1562 break; 1563 case BTSTAT_TARGET_IGNORED_ATN: 1564 case BTSTAT_OTHER_SCSI_BUS_RESET: 1565 case BTSTAT_HA_SCSI_BUS_RESET: 1566 if ((csio->ccb_h.status & CAM_STATUS_MASK) 1567 != CAM_CMD_TIMEOUT) 1568 csio->ccb_h.status = CAM_SCSI_BUS_RESET; 1569 break; 1570 case BTSTAT_HA_BDR: 1571 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) 1572 csio->ccb_h.status = CAM_BDR_SENT; 1573 else 1574 csio->ccb_h.status = CAM_CMD_TIMEOUT; 1575 break; 1576 case BTSTAT_INVALID_RECONNECT: 1577 case BTSTAT_ABORT_QUEUE_GENERATED: 1578 csio->ccb_h.status = CAM_REQ_TERMIO; 1579 break; 1580 case BTSTAT_SCSI_PERROR_DETECTED: 1581 csio->ccb_h.status = CAM_UNCOR_PARITY; 1582 break; 1583 } 1584 if (csio->ccb_h.status != CAM_REQ_CMP) { 1585 xpt_freeze_devq(csio->ccb_h.path, /*count*/1); 1586 csio->ccb_h.status |= CAM_DEV_QFRZN; 1587 } 1588 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1589 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1590 btfreeccb(bt, bccb); 1591 xpt_done(ccb); 1592 break; 1593 case BMBI_OK: 1594 /* All completed without incident */ 1595 ccb->ccb_h.status |= CAM_REQ_CMP; 1596 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1597 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1598 btfreeccb(bt, bccb); 1599 xpt_done(ccb); 1600 break; 1601 } 1602} 1603 1604static int 1605btreset(struct bt_softc* bt, int hard_reset) 1606{ 1607 struct ccb_hdr *ccb_h; 1608 u_int status; 1609 u_int timeout; 1610 u_int8_t reset_type; 1611 1612 if (hard_reset != 0) 1613 reset_type = HARD_RESET; 1614 else 1615 reset_type = SOFT_RESET; 1616 bt_outb(bt, CONTROL_REG, reset_type); 1617 1618 /* Wait 5sec. for Diagnostic start */ 1619 timeout = 5 * 10000; 1620 while (--timeout) { 1621 status = bt_inb(bt, STATUS_REG); 1622 if ((status & DIAG_ACTIVE) != 0) 1623 break; 1624 DELAY(100); 1625 } 1626 if (timeout == 0) { 1627 if (bootverbose) 1628 printf("%s: btreset - Diagnostic Active failed to " 1629 "assert. status = 0x%x\n", bt_name(bt), status); 1630 return (ETIMEDOUT); 1631 } 1632 1633 /* Wait 10sec. for Diagnostic end */ 1634 timeout = 10 * 10000; 1635 while (--timeout) { 1636 status = bt_inb(bt, STATUS_REG); 1637 if ((status & DIAG_ACTIVE) == 0) 1638 break; 1639 DELAY(100); 1640 } 1641 if (timeout == 0) { 1642 panic("%s: btreset - Diagnostic Active failed to drop. " 1643 "status = 0x%x\n", bt_name(bt), status); 1644 return (ETIMEDOUT); 1645 } 1646 1647 /* Wait for the host adapter to become ready or report a failure */ 1648 timeout = 10000; 1649 while (--timeout) { 1650 status = bt_inb(bt, STATUS_REG); 1651 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0) 1652 break; 1653 DELAY(100); 1654 } 1655 if (timeout == 0) { 1656 printf("%s: btreset - Host adapter failed to come ready. " 1657 "status = 0x%x\n", bt_name(bt), status); 1658 return (ETIMEDOUT); 1659 } 1660 1661 /* If the diagnostics failed, tell the user */ 1662 if ((status & DIAG_FAIL) != 0 1663 || (status & HA_READY) == 0) { 1664 printf("%s: btreset - Adapter failed diagnostics\n", 1665 bt_name(bt)); 1666 1667 if ((status & DATAIN_REG_READY) != 0) 1668 printf("%s: btreset - Host Adapter Error code = 0x%x\n", 1669 bt_name(bt), bt_inb(bt, DATAIN_REG)); 1670 return (ENXIO); 1671 } 1672 1673 /* If we've allocated mailboxes, initialize them */ 1674 if (bt->init_level > 4) 1675 btinitmboxes(bt); 1676 1677 /* If we've attached to the XPT, tell it about the event */ 1678 if (bt->path != NULL) 1679 xpt_async(AC_BUS_RESET, bt->path, NULL); 1680 1681 /* 1682 * Perform completion processing for all outstanding CCBs. 1683 */ 1684 while ((ccb_h = LIST_FIRST(&bt->pending_ccbs)) != NULL) { 1685 struct bt_ccb *pending_bccb; 1686 1687 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1688 pending_bccb->hccb.btstat = BTSTAT_HA_SCSI_BUS_RESET; 1689 btdone(bt, pending_bccb, BMBI_ERROR); 1690 } 1691 1692 return (0); 1693} 1694 1695/* 1696 * Send a command to the adapter. 1697 */ 1698int 1699bt_cmd(struct bt_softc *bt, bt_op_t opcode, u_int8_t *params, u_int param_len, 1700 u_int8_t *reply_data, u_int reply_len, u_int cmd_timeout) 1701{ 1702 u_int timeout; 1703 u_int status; 1704 u_int intstat; 1705 u_int reply_buf_size; 1706 int s; 1707 1708 /* No data returned to start */ 1709 reply_buf_size = reply_len; 1710 reply_len = 0; 1711 intstat = 0; 1712 1713 bt->command_cmp = 0; 1714 /* 1715 * Wait up to 1 sec. for the adapter to become 1716 * ready to accept commands. 1717 */ 1718 timeout = 10000; 1719 while (--timeout) { 1720 1721 status = bt_inb(bt, STATUS_REG); 1722 if ((status & HA_READY) != 0 1723 && (status & CMD_REG_BUSY) == 0) 1724 break; 1725 DELAY(100); 1726 } 1727 if (timeout == 0) { 1728 printf("%s: bt_cmd: Timeout waiting for adapter ready, " 1729 "status = 0x%x\n", bt_name(bt), status); 1730 return (ETIMEDOUT); 1731 } 1732 1733 /* 1734 * Send the opcode followed by any necessary parameter bytes. 1735 */ 1736 bt_outb(bt, COMMAND_REG, opcode); 1737 1738 /* 1739 * Wait for up to 1sec to get the parameter list sent 1740 */ 1741 timeout = 10000; 1742 while (param_len && --timeout) { 1743 DELAY(100); 1744 status = bt_inb(bt, STATUS_REG); 1745 intstat = bt_inb(bt, INTSTAT_REG); 1746 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1747 == (INTR_PENDING|CMD_COMPLETE)) 1748 break; 1749 if (bt->command_cmp != 0) { 1750 status = bt->latched_status; 1751 break; 1752 } 1753 if ((status & DATAIN_REG_READY) != 0) 1754 break; 1755 if ((status & CMD_REG_BUSY) == 0) { 1756 bt_outb(bt, COMMAND_REG, *params++); 1757 param_len--; 1758 } 1759 } 1760 if (timeout == 0) { 1761 printf("%s: bt_cmd: Timeout sending parameters, " 1762 "status = 0x%x\n", bt_name(bt), status); 1763 return (ETIMEDOUT); 1764 } 1765 1766 /* 1767 * The BOP_MODIFY_IO_ADDR does not issue a CMD_COMPLETE, but 1768 * it should update the status register. So, we wait for 1769 * the CMD_REG_BUSY status to clear and check for a command 1770 * failure. 1771 */ 1772 if (opcode == BOP_MODIFY_IO_ADDR) { 1773 1774 while (--cmd_timeout) { 1775 status = bt_inb(bt, STATUS_REG); 1776 if ((status & CMD_REG_BUSY) == 0) { 1777 if ((status & CMD_INVALID) != 0) { 1778 printf("%s: bt_cmd - Modify I/O Address" 1779 " invalid\n", bt_name(bt)); 1780 return (EINVAL); 1781 } 1782 return (0); 1783 } 1784 DELAY(100); 1785 } 1786 if (timeout == 0) { 1787 printf("%s: bt_cmd: Timeout on Modify I/O Address CMD, " 1788 "status = 0x%x\n", bt_name(bt), status); 1789 return (ETIMEDOUT); 1790 } 1791 } 1792 1793 /* 1794 * For all other commands, we wait for any output data 1795 * and the final comand completion interrupt. 1796 */ 1797 while (--cmd_timeout) { 1798 1799 status = bt_inb(bt, STATUS_REG); 1800 intstat = bt_inb(bt, INTSTAT_REG); 1801 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1802 == (INTR_PENDING|CMD_COMPLETE)) 1803 break; 1804 1805 if (bt->command_cmp != 0) { 1806 status = bt->latched_status; 1807 break; 1808 } 1809 1810 if ((status & DATAIN_REG_READY) != 0) { 1811 u_int8_t data; 1812 1813 data = bt_inb(bt, DATAIN_REG); 1814 if (reply_len < reply_buf_size) { 1815 *reply_data++ = data; 1816 } else { 1817 printf("%s: bt_cmd - Discarded reply data byte " 1818 "for opcode 0x%x\n", bt_name(bt), 1819 opcode); 1820 } 1821 reply_len++; 1822 } 1823 1824 if ((opcode == BOP_FETCH_LRAM) 1825 && (status & HA_READY) != 0) 1826 break; 1827 DELAY(100); 1828 } 1829 if (timeout == 0) { 1830 printf("%s: bt_cmd: Timeout waiting for reply data and " 1831 "command complete.\n%s: status = 0x%x, intstat = 0x%x, " 1832 "reply_len = %d\n", bt_name(bt), bt_name(bt), status, 1833 intstat, reply_len); 1834 return (ETIMEDOUT); 1835 } 1836 1837 /* 1838 * Clear any pending interrupts. Block interrupts so our 1839 * interrupt handler is not re-entered. 1840 */ 1841 s = splcam(); 1842 bt_intr(bt); 1843 splx(s); 1844 1845 /* 1846 * If the command was rejected by the controller, tell the caller. 1847 */ 1848 if ((status & CMD_INVALID) != 0) { 1849 /* 1850 * Some early adapters may not recover properly from 1851 * an invalid command. If it appears that the controller 1852 * has wedged (i.e. status was not cleared by our interrupt 1853 * reset above), perform a soft reset. 1854 */ 1855 if (bootverbose) 1856 printf("%s: Invalid Command 0x%x\n", bt_name(bt), 1857 opcode); 1858 DELAY(1000); 1859 status = bt_inb(bt, STATUS_REG); 1860 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY| 1861 CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0 1862 || (status & (HA_READY|INIT_REQUIRED)) 1863 != (HA_READY|INIT_REQUIRED)) { 1864 btreset(bt, /*hard_reset*/FALSE); 1865 } 1866 return (EINVAL); 1867 } 1868 1869 1870 if (param_len > 0) { 1871 /* The controller did not accept the full argument list */ 1872 return (E2BIG); 1873 } 1874 1875 if (reply_len != reply_buf_size) { 1876 /* Too much or too little data received */ 1877 return (EMSGSIZE); 1878 } 1879 1880 /* We were successful */ 1881 return (0); 1882} 1883 1884static int 1885btinitmboxes(struct bt_softc *bt) { 1886 init_32b_mbox_params_t init_mbox; 1887 int error; 1888 1889 bzero(bt->in_boxes, sizeof(bt_mbox_in_t) * bt->num_boxes); 1890 bzero(bt->out_boxes, sizeof(bt_mbox_out_t) * bt->num_boxes); 1891 bt->cur_inbox = bt->in_boxes; 1892 bt->last_inbox = bt->in_boxes + bt->num_boxes - 1; 1893 bt->cur_outbox = bt->out_boxes; 1894 bt->last_outbox = bt->out_boxes + bt->num_boxes - 1; 1895 1896 /* Tell the adapter about them */ 1897 init_mbox.num_boxes = bt->num_boxes; 1898 init_mbox.base_addr[0] = bt->mailbox_physbase & 0xFF; 1899 init_mbox.base_addr[1] = (bt->mailbox_physbase >> 8) & 0xFF; 1900 init_mbox.base_addr[2] = (bt->mailbox_physbase >> 16) & 0xFF; 1901 init_mbox.base_addr[3] = (bt->mailbox_physbase >> 24) & 0xFF; 1902 error = bt_cmd(bt, BOP_INITIALIZE_32BMBOX, (u_int8_t *)&init_mbox, 1903 /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL, 1904 /*reply_len*/0, DEFAULT_CMD_TIMEOUT); 1905 1906 if (error != 0) 1907 printf("btinitmboxes: Initialization command failed\n"); 1908 else if (bt->strict_rr != 0) { 1909 /* 1910 * If the controller supports 1911 * strict round robin mode, 1912 * enable it 1913 */ 1914 u_int8_t param; 1915 1916 param = 0; 1917 error = bt_cmd(bt, BOP_ENABLE_STRICT_RR, ¶m, 1, 1918 /*reply_buf*/NULL, /*reply_len*/0, 1919 DEFAULT_CMD_TIMEOUT); 1920 1921 if (error != 0) { 1922 printf("btinitmboxes: Unable to enable strict RR\n"); 1923 error = 0; 1924 } else if (bootverbose) { 1925 printf("%s: Using Strict Round Robin Mailbox Mode\n", 1926 bt_name(bt)); 1927 } 1928 } 1929 1930 return (error); 1931} 1932 1933/* 1934 * Update the XPT's idea of the negotiated transfer 1935 * parameters for a particular target. 1936 */ 1937static void 1938btfetchtransinfo(struct bt_softc *bt, struct ccb_trans_settings* cts) 1939{ 1940 setup_data_t setup_info; 1941 u_int target; 1942 u_int targ_offset; 1943 u_int targ_mask; 1944 u_int sync_period; 1945 int error; 1946 u_int8_t param; 1947 targ_syncinfo_t sync_info; 1948 1949 target = cts->ccb_h.target_id; 1950 targ_offset = (target & 0x7); 1951 targ_mask = (0x01 << targ_offset); 1952 1953 /* 1954 * Inquire Setup Information. This command retreives the 1955 * Wide negotiation status for recent adapters as well as 1956 * the sync info for older models. 1957 */ 1958 param = sizeof(setup_info); 1959 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, ¶m, /*paramlen*/1, 1960 (u_int8_t*)&setup_info, sizeof(setup_info), 1961 DEFAULT_CMD_TIMEOUT); 1962 1963 if (error != 0) { 1964 printf("%s: btfetchtransinfo - Inquire Setup Info Failed\n", 1965 bt_name(bt)); 1966 return; 1967 } 1968 1969 sync_info = (target < 8) ? setup_info.low_syncinfo[targ_offset] 1970 : setup_info.high_syncinfo[targ_offset]; 1971 1972 if (sync_info.sync == 0) 1973 cts->sync_offset = 0; 1974 else 1975 cts->sync_offset = sync_info.offset; 1976 1977 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1978 if (strcmp(bt->firmware_ver, "5.06L") >= 0) { 1979 u_int wide_active; 1980 1981 wide_active = 1982 (target < 8) ? (setup_info.low_wide_active & targ_mask) 1983 : (setup_info.high_wide_active & targ_mask); 1984 1985 if (wide_active) 1986 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1987 } else if ((bt->wide_permitted & targ_mask) != 0) { 1988 struct ccb_getdev cgd; 1989 1990 /* 1991 * Prior to rev 5.06L, wide status isn't provided, 1992 * so we "guess" that wide transfers are in effect 1993 * if the user settings allow for wide and the inquiry 1994 * data for the device indicates that it can handle 1995 * wide transfers. 1996 */ 1997 xpt_setup_ccb(&cgd.ccb_h, cts->ccb_h.path, /*priority*/1); 1998 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 1999 xpt_action((union ccb *)&cgd); 2000 if ((cgd.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP 2001 && (cgd.inq_data.flags & SID_WBus16) != 0) 2002 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 2003 } 2004 2005 if (bt->firmware_ver[0] >= 3) { 2006 /* 2007 * For adapters that can do fast or ultra speeds, 2008 * use the more exact Target Sync Information command. 2009 */ 2010 target_sync_info_data_t sync_info; 2011 2012 param = sizeof(sync_info); 2013 error = bt_cmd(bt, BOP_TARG_SYNC_INFO, ¶m, /*paramlen*/1, 2014 (u_int8_t*)&sync_info, sizeof(sync_info), 2015 DEFAULT_CMD_TIMEOUT); 2016 2017 if (error != 0) { 2018 printf("%s: btfetchtransinfo - Inquire Sync " 2019 "Info Failed 0x%x\n", bt_name(bt), error); 2020 return; 2021 } 2022 sync_period = sync_info.sync_rate[target] * 100; 2023 } else { 2024 sync_period = 2000 + (500 * sync_info.period); 2025 } 2026 2027 /* Convert ns value to standard SCSI sync rate */ 2028 if (cts->sync_offset != 0) 2029 cts->sync_period = scsi_calc_syncparam(sync_period); 2030 else 2031 cts->sync_period = 0; 2032 2033 cts->valid = CCB_TRANS_SYNC_RATE_VALID 2034 | CCB_TRANS_SYNC_OFFSET_VALID 2035 | CCB_TRANS_BUS_WIDTH_VALID; 2036 xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); 2037} 2038 2039static void 2040btmapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2041{ 2042 struct bt_softc* bt; 2043 2044 bt = (struct bt_softc*)arg; 2045 bt->mailbox_physbase = segs->ds_addr; 2046} 2047 2048static void 2049btmapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2050{ 2051 struct bt_softc* bt; 2052 2053 bt = (struct bt_softc*)arg; 2054 bt->bt_ccb_physbase = segs->ds_addr; 2055} 2056 2057static void 2058btmapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2059{ 2060 2061 struct bt_softc* bt; 2062 2063 bt = (struct bt_softc*)arg; 2064 SLIST_FIRST(&bt->sg_maps)->sg_physaddr = segs->ds_addr; 2065} 2066 2067static void 2068btpoll(struct cam_sim *sim) 2069{ 2070 bt_intr(cam_sim_softc(sim)); 2071} 2072 2073void 2074bttimeout(void *arg) 2075{ 2076 struct bt_ccb *bccb; 2077 union ccb *ccb; 2078 struct bt_softc *bt; 2079 int s; 2080 2081 bccb = (struct bt_ccb *)arg; 2082 ccb = bccb->ccb; 2083 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 2084 xpt_print_path(ccb->ccb_h.path); 2085 printf("CCB %p - timed out\n", (void *)bccb); 2086 2087 s = splcam(); 2088 2089 if ((bccb->flags & BCCB_ACTIVE) == 0) { 2090 xpt_print_path(ccb->ccb_h.path); 2091 printf("CCB %p - timed out CCB already completed\n", 2092 (void *)bccb); 2093 splx(s); 2094 return; 2095 } 2096 2097 /* 2098 * In order to simplify the recovery process, we ask the XPT 2099 * layer to halt the queue of new transactions and we traverse 2100 * the list of pending CCBs and remove their timeouts. This 2101 * means that the driver attempts to clear only one error 2102 * condition at a time. In general, timeouts that occur 2103 * close together are related anyway, so there is no benefit 2104 * in attempting to handle errors in parrallel. Timeouts will 2105 * be reinstated when the recovery process ends. 2106 */ 2107 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) { 2108 struct ccb_hdr *ccb_h; 2109 2110 if ((bccb->flags & BCCB_RELEASE_SIMQ) == 0) { 2111 xpt_freeze_simq(bt->sim, /*count*/1); 2112 bccb->flags |= BCCB_RELEASE_SIMQ; 2113 } 2114 2115 ccb_h = LIST_FIRST(&bt->pending_ccbs); 2116 while (ccb_h != NULL) { 2117 struct bt_ccb *pending_bccb; 2118 2119 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 2120 untimeout(bttimeout, pending_bccb, ccb_h->timeout_ch); 2121 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 2122 } 2123 } 2124 2125 if ((bccb->flags & BCCB_DEVICE_RESET) != 0 2126 || bt->cur_outbox->action_code != BMBO_FREE 2127 || ((bccb->hccb.tag_enable == TRUE) 2128 && (bt->firmware_ver[0] < '5'))) { 2129 /* 2130 * Try a full host adapter/SCSI bus reset. 2131 * We do this only if we have already attempted 2132 * to clear the condition with a BDR, or we cannot 2133 * attempt a BDR for lack of mailbox resources 2134 * or because of faulty firmware. It turns out 2135 * that firmware versions prior to 5.xx treat BDRs 2136 * as untagged commands that cannot be sent until 2137 * all outstanding tagged commands have been processed. 2138 * This makes it somewhat difficult to use a BDR to 2139 * clear up a problem with an uncompleted tagged command. 2140 */ 2141 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 2142 btreset(bt, /*hardreset*/TRUE); 2143 printf("%s: No longer in timeout\n", bt_name(bt)); 2144 } else { 2145 /* 2146 * Send a Bus Device Reset message: 2147 * The target that is holding up the bus may not 2148 * be the same as the one that triggered this timeout 2149 * (different commands have different timeout lengths), 2150 * but we have no way of determining this from our 2151 * timeout handler. Our strategy here is to queue a 2152 * BDR message to the target of the timed out command. 2153 * If this fails, we'll get another timeout 2 seconds 2154 * later which will attempt a bus reset. 2155 */ 2156 bccb->flags |= BCCB_DEVICE_RESET; 2157 ccb->ccb_h.timeout_ch = 2158 timeout(bttimeout, (caddr_t)bccb, 2 * hz); 2159 2160 bt->recovery_bccb->hccb.opcode = INITIATOR_BUS_DEV_RESET; 2161 2162 /* No Data Transfer */ 2163 bt->recovery_bccb->hccb.datain = TRUE; 2164 bt->recovery_bccb->hccb.dataout = TRUE; 2165 bt->recovery_bccb->hccb.btstat = 0; 2166 bt->recovery_bccb->hccb.sdstat = 0; 2167 bt->recovery_bccb->hccb.target_id = ccb->ccb_h.target_id; 2168 2169 /* Tell the adapter about this command */ 2170 bt->cur_outbox->ccb_addr = btccbvtop(bt, bt->recovery_bccb); 2171 bt->cur_outbox->action_code = BMBO_START; 2172 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 2173 btnextoutbox(bt); 2174 } 2175 2176 splx(s); 2177} 2178
| 1555 csio->ccb_h.status = CAM_DATA_RUN_ERR; 1556 break; 1557 } 1558 /* FALLTHROUGH */ 1559 case BTSTAT_NOERROR: 1560 case BTSTAT_LINKED_CMD_COMPLETE: 1561 case BTSTAT_LINKED_CMD_FLAG_COMPLETE: 1562 case BTSTAT_DATAUNDERUN_ERROR: 1563 1564 csio->scsi_status = bccb->hccb.sdstat; 1565 csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1566 switch(csio->scsi_status) { 1567 case SCSI_STATUS_CHECK_COND: 1568 case SCSI_STATUS_CMD_TERMINATED: 1569 csio->ccb_h.status |= CAM_AUTOSNS_VALID; 1570 /* Bounce sense back if necessary */ 1571 if (bt->sense_buffers != NULL) { 1572 csio->sense_data = 1573 *btsensevaddr(bt, bccb); 1574 } 1575 break; 1576 default: 1577 break; 1578 case SCSI_STATUS_OK: 1579 csio->ccb_h.status = CAM_REQ_CMP; 1580 break; 1581 } 1582 csio->resid = bccb->hccb.data_len; 1583 break; 1584 case BTSTAT_SELTIMEOUT: 1585 csio->ccb_h.status = CAM_SEL_TIMEOUT; 1586 break; 1587 case BTSTAT_UNEXPECTED_BUSFREE: 1588 csio->ccb_h.status = CAM_UNEXP_BUSFREE; 1589 break; 1590 case BTSTAT_INVALID_PHASE: 1591 csio->ccb_h.status = CAM_SEQUENCE_FAIL; 1592 break; 1593 case BTSTAT_INVALID_ACTION_CODE: 1594 panic("%s: Inavlid Action code", bt_name(bt)); 1595 break; 1596 case BTSTAT_INVALID_OPCODE: 1597 panic("%s: Inavlid CCB Opcode code", bt_name(bt)); 1598 break; 1599 case BTSTAT_LINKED_CCB_LUN_MISMATCH: 1600 /* We don't even support linked commands... */ 1601 panic("%s: Linked CCB Lun Mismatch", bt_name(bt)); 1602 break; 1603 case BTSTAT_INVALID_CCB_OR_SG_PARAM: 1604 panic("%s: Invalid CCB or SG list", bt_name(bt)); 1605 break; 1606 case BTSTAT_AUTOSENSE_FAILED: 1607 csio->ccb_h.status = CAM_AUTOSENSE_FAIL; 1608 break; 1609 case BTSTAT_TAGGED_MSG_REJECTED: 1610 { 1611 struct ccb_trans_settings neg; 1612 1613 xpt_print_path(csio->ccb_h.path); 1614 printf("refuses tagged commands. Performing " 1615 "non-tagged I/O\n"); 1616 neg.flags = 0; 1617 neg.valid = CCB_TRANS_TQ_VALID; 1618 xpt_setup_ccb(&neg.ccb_h, csio->ccb_h.path, 1619 /*priority*/1); 1620 xpt_async(AC_TRANSFER_NEG, csio->ccb_h.path, &neg); 1621 bt->tags_permitted &= ~(0x01 << csio->ccb_h.target_id); 1622 csio->ccb_h.status = CAM_MSG_REJECT_REC; 1623 break; 1624 } 1625 case BTSTAT_UNSUPPORTED_MSG_RECEIVED: 1626 /* 1627 * XXX You would think that this is 1628 * a recoverable error... Hmmm. 1629 */ 1630 csio->ccb_h.status = CAM_REQ_CMP_ERR; 1631 break; 1632 case BTSTAT_HA_SOFTWARE_ERROR: 1633 case BTSTAT_HA_WATCHDOG_ERROR: 1634 case BTSTAT_HARDWARE_FAILURE: 1635 /* Hardware reset ??? Can we recover ??? */ 1636 csio->ccb_h.status = CAM_NO_HBA; 1637 break; 1638 case BTSTAT_TARGET_IGNORED_ATN: 1639 case BTSTAT_OTHER_SCSI_BUS_RESET: 1640 case BTSTAT_HA_SCSI_BUS_RESET: 1641 if ((csio->ccb_h.status & CAM_STATUS_MASK) 1642 != CAM_CMD_TIMEOUT) 1643 csio->ccb_h.status = CAM_SCSI_BUS_RESET; 1644 break; 1645 case BTSTAT_HA_BDR: 1646 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) 1647 csio->ccb_h.status = CAM_BDR_SENT; 1648 else 1649 csio->ccb_h.status = CAM_CMD_TIMEOUT; 1650 break; 1651 case BTSTAT_INVALID_RECONNECT: 1652 case BTSTAT_ABORT_QUEUE_GENERATED: 1653 csio->ccb_h.status = CAM_REQ_TERMIO; 1654 break; 1655 case BTSTAT_SCSI_PERROR_DETECTED: 1656 csio->ccb_h.status = CAM_UNCOR_PARITY; 1657 break; 1658 } 1659 if (csio->ccb_h.status != CAM_REQ_CMP) { 1660 xpt_freeze_devq(csio->ccb_h.path, /*count*/1); 1661 csio->ccb_h.status |= CAM_DEV_QFRZN; 1662 } 1663 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1664 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1665 btfreeccb(bt, bccb); 1666 xpt_done(ccb); 1667 break; 1668 case BMBI_OK: 1669 /* All completed without incident */ 1670 ccb->ccb_h.status |= CAM_REQ_CMP; 1671 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0) 1672 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1673 btfreeccb(bt, bccb); 1674 xpt_done(ccb); 1675 break; 1676 } 1677} 1678 1679static int 1680btreset(struct bt_softc* bt, int hard_reset) 1681{ 1682 struct ccb_hdr *ccb_h; 1683 u_int status; 1684 u_int timeout; 1685 u_int8_t reset_type; 1686 1687 if (hard_reset != 0) 1688 reset_type = HARD_RESET; 1689 else 1690 reset_type = SOFT_RESET; 1691 bt_outb(bt, CONTROL_REG, reset_type); 1692 1693 /* Wait 5sec. for Diagnostic start */ 1694 timeout = 5 * 10000; 1695 while (--timeout) { 1696 status = bt_inb(bt, STATUS_REG); 1697 if ((status & DIAG_ACTIVE) != 0) 1698 break; 1699 DELAY(100); 1700 } 1701 if (timeout == 0) { 1702 if (bootverbose) 1703 printf("%s: btreset - Diagnostic Active failed to " 1704 "assert. status = 0x%x\n", bt_name(bt), status); 1705 return (ETIMEDOUT); 1706 } 1707 1708 /* Wait 10sec. for Diagnostic end */ 1709 timeout = 10 * 10000; 1710 while (--timeout) { 1711 status = bt_inb(bt, STATUS_REG); 1712 if ((status & DIAG_ACTIVE) == 0) 1713 break; 1714 DELAY(100); 1715 } 1716 if (timeout == 0) { 1717 panic("%s: btreset - Diagnostic Active failed to drop. " 1718 "status = 0x%x\n", bt_name(bt), status); 1719 return (ETIMEDOUT); 1720 } 1721 1722 /* Wait for the host adapter to become ready or report a failure */ 1723 timeout = 10000; 1724 while (--timeout) { 1725 status = bt_inb(bt, STATUS_REG); 1726 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0) 1727 break; 1728 DELAY(100); 1729 } 1730 if (timeout == 0) { 1731 printf("%s: btreset - Host adapter failed to come ready. " 1732 "status = 0x%x\n", bt_name(bt), status); 1733 return (ETIMEDOUT); 1734 } 1735 1736 /* If the diagnostics failed, tell the user */ 1737 if ((status & DIAG_FAIL) != 0 1738 || (status & HA_READY) == 0) { 1739 printf("%s: btreset - Adapter failed diagnostics\n", 1740 bt_name(bt)); 1741 1742 if ((status & DATAIN_REG_READY) != 0) 1743 printf("%s: btreset - Host Adapter Error code = 0x%x\n", 1744 bt_name(bt), bt_inb(bt, DATAIN_REG)); 1745 return (ENXIO); 1746 } 1747 1748 /* If we've allocated mailboxes, initialize them */ 1749 if (bt->init_level > 4) 1750 btinitmboxes(bt); 1751 1752 /* If we've attached to the XPT, tell it about the event */ 1753 if (bt->path != NULL) 1754 xpt_async(AC_BUS_RESET, bt->path, NULL); 1755 1756 /* 1757 * Perform completion processing for all outstanding CCBs. 1758 */ 1759 while ((ccb_h = LIST_FIRST(&bt->pending_ccbs)) != NULL) { 1760 struct bt_ccb *pending_bccb; 1761 1762 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 1763 pending_bccb->hccb.btstat = BTSTAT_HA_SCSI_BUS_RESET; 1764 btdone(bt, pending_bccb, BMBI_ERROR); 1765 } 1766 1767 return (0); 1768} 1769 1770/* 1771 * Send a command to the adapter. 1772 */ 1773int 1774bt_cmd(struct bt_softc *bt, bt_op_t opcode, u_int8_t *params, u_int param_len, 1775 u_int8_t *reply_data, u_int reply_len, u_int cmd_timeout) 1776{ 1777 u_int timeout; 1778 u_int status; 1779 u_int intstat; 1780 u_int reply_buf_size; 1781 int s; 1782 1783 /* No data returned to start */ 1784 reply_buf_size = reply_len; 1785 reply_len = 0; 1786 intstat = 0; 1787 1788 bt->command_cmp = 0; 1789 /* 1790 * Wait up to 1 sec. for the adapter to become 1791 * ready to accept commands. 1792 */ 1793 timeout = 10000; 1794 while (--timeout) { 1795 1796 status = bt_inb(bt, STATUS_REG); 1797 if ((status & HA_READY) != 0 1798 && (status & CMD_REG_BUSY) == 0) 1799 break; 1800 DELAY(100); 1801 } 1802 if (timeout == 0) { 1803 printf("%s: bt_cmd: Timeout waiting for adapter ready, " 1804 "status = 0x%x\n", bt_name(bt), status); 1805 return (ETIMEDOUT); 1806 } 1807 1808 /* 1809 * Send the opcode followed by any necessary parameter bytes. 1810 */ 1811 bt_outb(bt, COMMAND_REG, opcode); 1812 1813 /* 1814 * Wait for up to 1sec to get the parameter list sent 1815 */ 1816 timeout = 10000; 1817 while (param_len && --timeout) { 1818 DELAY(100); 1819 status = bt_inb(bt, STATUS_REG); 1820 intstat = bt_inb(bt, INTSTAT_REG); 1821 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1822 == (INTR_PENDING|CMD_COMPLETE)) 1823 break; 1824 if (bt->command_cmp != 0) { 1825 status = bt->latched_status; 1826 break; 1827 } 1828 if ((status & DATAIN_REG_READY) != 0) 1829 break; 1830 if ((status & CMD_REG_BUSY) == 0) { 1831 bt_outb(bt, COMMAND_REG, *params++); 1832 param_len--; 1833 } 1834 } 1835 if (timeout == 0) { 1836 printf("%s: bt_cmd: Timeout sending parameters, " 1837 "status = 0x%x\n", bt_name(bt), status); 1838 return (ETIMEDOUT); 1839 } 1840 1841 /* 1842 * The BOP_MODIFY_IO_ADDR does not issue a CMD_COMPLETE, but 1843 * it should update the status register. So, we wait for 1844 * the CMD_REG_BUSY status to clear and check for a command 1845 * failure. 1846 */ 1847 if (opcode == BOP_MODIFY_IO_ADDR) { 1848 1849 while (--cmd_timeout) { 1850 status = bt_inb(bt, STATUS_REG); 1851 if ((status & CMD_REG_BUSY) == 0) { 1852 if ((status & CMD_INVALID) != 0) { 1853 printf("%s: bt_cmd - Modify I/O Address" 1854 " invalid\n", bt_name(bt)); 1855 return (EINVAL); 1856 } 1857 return (0); 1858 } 1859 DELAY(100); 1860 } 1861 if (timeout == 0) { 1862 printf("%s: bt_cmd: Timeout on Modify I/O Address CMD, " 1863 "status = 0x%x\n", bt_name(bt), status); 1864 return (ETIMEDOUT); 1865 } 1866 } 1867 1868 /* 1869 * For all other commands, we wait for any output data 1870 * and the final comand completion interrupt. 1871 */ 1872 while (--cmd_timeout) { 1873 1874 status = bt_inb(bt, STATUS_REG); 1875 intstat = bt_inb(bt, INTSTAT_REG); 1876 if ((intstat & (INTR_PENDING|CMD_COMPLETE)) 1877 == (INTR_PENDING|CMD_COMPLETE)) 1878 break; 1879 1880 if (bt->command_cmp != 0) { 1881 status = bt->latched_status; 1882 break; 1883 } 1884 1885 if ((status & DATAIN_REG_READY) != 0) { 1886 u_int8_t data; 1887 1888 data = bt_inb(bt, DATAIN_REG); 1889 if (reply_len < reply_buf_size) { 1890 *reply_data++ = data; 1891 } else { 1892 printf("%s: bt_cmd - Discarded reply data byte " 1893 "for opcode 0x%x\n", bt_name(bt), 1894 opcode); 1895 } 1896 reply_len++; 1897 } 1898 1899 if ((opcode == BOP_FETCH_LRAM) 1900 && (status & HA_READY) != 0) 1901 break; 1902 DELAY(100); 1903 } 1904 if (timeout == 0) { 1905 printf("%s: bt_cmd: Timeout waiting for reply data and " 1906 "command complete.\n%s: status = 0x%x, intstat = 0x%x, " 1907 "reply_len = %d\n", bt_name(bt), bt_name(bt), status, 1908 intstat, reply_len); 1909 return (ETIMEDOUT); 1910 } 1911 1912 /* 1913 * Clear any pending interrupts. Block interrupts so our 1914 * interrupt handler is not re-entered. 1915 */ 1916 s = splcam(); 1917 bt_intr(bt); 1918 splx(s); 1919 1920 /* 1921 * If the command was rejected by the controller, tell the caller. 1922 */ 1923 if ((status & CMD_INVALID) != 0) { 1924 /* 1925 * Some early adapters may not recover properly from 1926 * an invalid command. If it appears that the controller 1927 * has wedged (i.e. status was not cleared by our interrupt 1928 * reset above), perform a soft reset. 1929 */ 1930 if (bootverbose) 1931 printf("%s: Invalid Command 0x%x\n", bt_name(bt), 1932 opcode); 1933 DELAY(1000); 1934 status = bt_inb(bt, STATUS_REG); 1935 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY| 1936 CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0 1937 || (status & (HA_READY|INIT_REQUIRED)) 1938 != (HA_READY|INIT_REQUIRED)) { 1939 btreset(bt, /*hard_reset*/FALSE); 1940 } 1941 return (EINVAL); 1942 } 1943 1944 1945 if (param_len > 0) { 1946 /* The controller did not accept the full argument list */ 1947 return (E2BIG); 1948 } 1949 1950 if (reply_len != reply_buf_size) { 1951 /* Too much or too little data received */ 1952 return (EMSGSIZE); 1953 } 1954 1955 /* We were successful */ 1956 return (0); 1957} 1958 1959static int 1960btinitmboxes(struct bt_softc *bt) { 1961 init_32b_mbox_params_t init_mbox; 1962 int error; 1963 1964 bzero(bt->in_boxes, sizeof(bt_mbox_in_t) * bt->num_boxes); 1965 bzero(bt->out_boxes, sizeof(bt_mbox_out_t) * bt->num_boxes); 1966 bt->cur_inbox = bt->in_boxes; 1967 bt->last_inbox = bt->in_boxes + bt->num_boxes - 1; 1968 bt->cur_outbox = bt->out_boxes; 1969 bt->last_outbox = bt->out_boxes + bt->num_boxes - 1; 1970 1971 /* Tell the adapter about them */ 1972 init_mbox.num_boxes = bt->num_boxes; 1973 init_mbox.base_addr[0] = bt->mailbox_physbase & 0xFF; 1974 init_mbox.base_addr[1] = (bt->mailbox_physbase >> 8) & 0xFF; 1975 init_mbox.base_addr[2] = (bt->mailbox_physbase >> 16) & 0xFF; 1976 init_mbox.base_addr[3] = (bt->mailbox_physbase >> 24) & 0xFF; 1977 error = bt_cmd(bt, BOP_INITIALIZE_32BMBOX, (u_int8_t *)&init_mbox, 1978 /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL, 1979 /*reply_len*/0, DEFAULT_CMD_TIMEOUT); 1980 1981 if (error != 0) 1982 printf("btinitmboxes: Initialization command failed\n"); 1983 else if (bt->strict_rr != 0) { 1984 /* 1985 * If the controller supports 1986 * strict round robin mode, 1987 * enable it 1988 */ 1989 u_int8_t param; 1990 1991 param = 0; 1992 error = bt_cmd(bt, BOP_ENABLE_STRICT_RR, ¶m, 1, 1993 /*reply_buf*/NULL, /*reply_len*/0, 1994 DEFAULT_CMD_TIMEOUT); 1995 1996 if (error != 0) { 1997 printf("btinitmboxes: Unable to enable strict RR\n"); 1998 error = 0; 1999 } else if (bootverbose) { 2000 printf("%s: Using Strict Round Robin Mailbox Mode\n", 2001 bt_name(bt)); 2002 } 2003 } 2004 2005 return (error); 2006} 2007 2008/* 2009 * Update the XPT's idea of the negotiated transfer 2010 * parameters for a particular target. 2011 */ 2012static void 2013btfetchtransinfo(struct bt_softc *bt, struct ccb_trans_settings* cts) 2014{ 2015 setup_data_t setup_info; 2016 u_int target; 2017 u_int targ_offset; 2018 u_int targ_mask; 2019 u_int sync_period; 2020 int error; 2021 u_int8_t param; 2022 targ_syncinfo_t sync_info; 2023 2024 target = cts->ccb_h.target_id; 2025 targ_offset = (target & 0x7); 2026 targ_mask = (0x01 << targ_offset); 2027 2028 /* 2029 * Inquire Setup Information. This command retreives the 2030 * Wide negotiation status for recent adapters as well as 2031 * the sync info for older models. 2032 */ 2033 param = sizeof(setup_info); 2034 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, ¶m, /*paramlen*/1, 2035 (u_int8_t*)&setup_info, sizeof(setup_info), 2036 DEFAULT_CMD_TIMEOUT); 2037 2038 if (error != 0) { 2039 printf("%s: btfetchtransinfo - Inquire Setup Info Failed\n", 2040 bt_name(bt)); 2041 return; 2042 } 2043 2044 sync_info = (target < 8) ? setup_info.low_syncinfo[targ_offset] 2045 : setup_info.high_syncinfo[targ_offset]; 2046 2047 if (sync_info.sync == 0) 2048 cts->sync_offset = 0; 2049 else 2050 cts->sync_offset = sync_info.offset; 2051 2052 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 2053 if (strcmp(bt->firmware_ver, "5.06L") >= 0) { 2054 u_int wide_active; 2055 2056 wide_active = 2057 (target < 8) ? (setup_info.low_wide_active & targ_mask) 2058 : (setup_info.high_wide_active & targ_mask); 2059 2060 if (wide_active) 2061 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 2062 } else if ((bt->wide_permitted & targ_mask) != 0) { 2063 struct ccb_getdev cgd; 2064 2065 /* 2066 * Prior to rev 5.06L, wide status isn't provided, 2067 * so we "guess" that wide transfers are in effect 2068 * if the user settings allow for wide and the inquiry 2069 * data for the device indicates that it can handle 2070 * wide transfers. 2071 */ 2072 xpt_setup_ccb(&cgd.ccb_h, cts->ccb_h.path, /*priority*/1); 2073 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 2074 xpt_action((union ccb *)&cgd); 2075 if ((cgd.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP 2076 && (cgd.inq_data.flags & SID_WBus16) != 0) 2077 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 2078 } 2079 2080 if (bt->firmware_ver[0] >= 3) { 2081 /* 2082 * For adapters that can do fast or ultra speeds, 2083 * use the more exact Target Sync Information command. 2084 */ 2085 target_sync_info_data_t sync_info; 2086 2087 param = sizeof(sync_info); 2088 error = bt_cmd(bt, BOP_TARG_SYNC_INFO, ¶m, /*paramlen*/1, 2089 (u_int8_t*)&sync_info, sizeof(sync_info), 2090 DEFAULT_CMD_TIMEOUT); 2091 2092 if (error != 0) { 2093 printf("%s: btfetchtransinfo - Inquire Sync " 2094 "Info Failed 0x%x\n", bt_name(bt), error); 2095 return; 2096 } 2097 sync_period = sync_info.sync_rate[target] * 100; 2098 } else { 2099 sync_period = 2000 + (500 * sync_info.period); 2100 } 2101 2102 /* Convert ns value to standard SCSI sync rate */ 2103 if (cts->sync_offset != 0) 2104 cts->sync_period = scsi_calc_syncparam(sync_period); 2105 else 2106 cts->sync_period = 0; 2107 2108 cts->valid = CCB_TRANS_SYNC_RATE_VALID 2109 | CCB_TRANS_SYNC_OFFSET_VALID 2110 | CCB_TRANS_BUS_WIDTH_VALID; 2111 xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); 2112} 2113 2114static void 2115btmapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2116{ 2117 struct bt_softc* bt; 2118 2119 bt = (struct bt_softc*)arg; 2120 bt->mailbox_physbase = segs->ds_addr; 2121} 2122 2123static void 2124btmapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2125{ 2126 struct bt_softc* bt; 2127 2128 bt = (struct bt_softc*)arg; 2129 bt->bt_ccb_physbase = segs->ds_addr; 2130} 2131 2132static void 2133btmapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2134{ 2135 2136 struct bt_softc* bt; 2137 2138 bt = (struct bt_softc*)arg; 2139 SLIST_FIRST(&bt->sg_maps)->sg_physaddr = segs->ds_addr; 2140} 2141 2142static void 2143btpoll(struct cam_sim *sim) 2144{ 2145 bt_intr(cam_sim_softc(sim)); 2146} 2147 2148void 2149bttimeout(void *arg) 2150{ 2151 struct bt_ccb *bccb; 2152 union ccb *ccb; 2153 struct bt_softc *bt; 2154 int s; 2155 2156 bccb = (struct bt_ccb *)arg; 2157 ccb = bccb->ccb; 2158 bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr; 2159 xpt_print_path(ccb->ccb_h.path); 2160 printf("CCB %p - timed out\n", (void *)bccb); 2161 2162 s = splcam(); 2163 2164 if ((bccb->flags & BCCB_ACTIVE) == 0) { 2165 xpt_print_path(ccb->ccb_h.path); 2166 printf("CCB %p - timed out CCB already completed\n", 2167 (void *)bccb); 2168 splx(s); 2169 return; 2170 } 2171 2172 /* 2173 * In order to simplify the recovery process, we ask the XPT 2174 * layer to halt the queue of new transactions and we traverse 2175 * the list of pending CCBs and remove their timeouts. This 2176 * means that the driver attempts to clear only one error 2177 * condition at a time. In general, timeouts that occur 2178 * close together are related anyway, so there is no benefit 2179 * in attempting to handle errors in parrallel. Timeouts will 2180 * be reinstated when the recovery process ends. 2181 */ 2182 if ((bccb->flags & BCCB_DEVICE_RESET) == 0) { 2183 struct ccb_hdr *ccb_h; 2184 2185 if ((bccb->flags & BCCB_RELEASE_SIMQ) == 0) { 2186 xpt_freeze_simq(bt->sim, /*count*/1); 2187 bccb->flags |= BCCB_RELEASE_SIMQ; 2188 } 2189 2190 ccb_h = LIST_FIRST(&bt->pending_ccbs); 2191 while (ccb_h != NULL) { 2192 struct bt_ccb *pending_bccb; 2193 2194 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr; 2195 untimeout(bttimeout, pending_bccb, ccb_h->timeout_ch); 2196 ccb_h = LIST_NEXT(ccb_h, sim_links.le); 2197 } 2198 } 2199 2200 if ((bccb->flags & BCCB_DEVICE_RESET) != 0 2201 || bt->cur_outbox->action_code != BMBO_FREE 2202 || ((bccb->hccb.tag_enable == TRUE) 2203 && (bt->firmware_ver[0] < '5'))) { 2204 /* 2205 * Try a full host adapter/SCSI bus reset. 2206 * We do this only if we have already attempted 2207 * to clear the condition with a BDR, or we cannot 2208 * attempt a BDR for lack of mailbox resources 2209 * or because of faulty firmware. It turns out 2210 * that firmware versions prior to 5.xx treat BDRs 2211 * as untagged commands that cannot be sent until 2212 * all outstanding tagged commands have been processed. 2213 * This makes it somewhat difficult to use a BDR to 2214 * clear up a problem with an uncompleted tagged command. 2215 */ 2216 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 2217 btreset(bt, /*hardreset*/TRUE); 2218 printf("%s: No longer in timeout\n", bt_name(bt)); 2219 } else { 2220 /* 2221 * Send a Bus Device Reset message: 2222 * The target that is holding up the bus may not 2223 * be the same as the one that triggered this timeout 2224 * (different commands have different timeout lengths), 2225 * but we have no way of determining this from our 2226 * timeout handler. Our strategy here is to queue a 2227 * BDR message to the target of the timed out command. 2228 * If this fails, we'll get another timeout 2 seconds 2229 * later which will attempt a bus reset. 2230 */ 2231 bccb->flags |= BCCB_DEVICE_RESET; 2232 ccb->ccb_h.timeout_ch = 2233 timeout(bttimeout, (caddr_t)bccb, 2 * hz); 2234 2235 bt->recovery_bccb->hccb.opcode = INITIATOR_BUS_DEV_RESET; 2236 2237 /* No Data Transfer */ 2238 bt->recovery_bccb->hccb.datain = TRUE; 2239 bt->recovery_bccb->hccb.dataout = TRUE; 2240 bt->recovery_bccb->hccb.btstat = 0; 2241 bt->recovery_bccb->hccb.sdstat = 0; 2242 bt->recovery_bccb->hccb.target_id = ccb->ccb_h.target_id; 2243 2244 /* Tell the adapter about this command */ 2245 bt->cur_outbox->ccb_addr = btccbvtop(bt, bt->recovery_bccb); 2246 bt->cur_outbox->action_code = BMBO_START; 2247 bt_outb(bt, COMMAND_REG, BOP_START_MBOX); 2248 btnextoutbox(bt); 2249 } 2250 2251 splx(s); 2252} 2253
|