TAILQ_INSERT_HEAD(&gdt->sc_free_ccb, &gdt->sc_ccbs[i],
TAILQ_INSERT_TAIL(&gdt->sc_free_ccb, &gdt->sc_ccbs[i],
gdt_attach(gdt)	struct gdt_softc *gdt;{	u_int16_t cdev_cnt;	int i, id, drv_cyls, drv_hds, drv_secs;	gdt_polling = 1;	gdt_from_wait = 0;	gdt_clear_events(gdt);	TAILQ_INIT(&gdt->sc_free_ccb);	TAILQ_INIT(&gdt->sc_ccbq);	LIST_INIT(&gdt->sc_queue);	/* Initialize the ccbs */	for (i = 0; i < GDT_MAXCMDS; i++) {		gdt->sc_ccbs[i].gc_cmd_index = i + 2;		(void)gdt_ccb_set_cmd(gdt->sc_ccbs + i, GDT_GCF_UNUSED);		TAILQ_INSERT_HEAD(&gdt->sc_free_ccb, &gdt->sc_ccbs[i],		    gc_chain);	}	/* Fill in the prototype scsi_link. */	gdt->sc_link.adapter_softc = gdt;	gdt->sc_link.adapter = &gdt_switch;	gdt->sc_link.adapter_target = 7;	gdt->sc_link.device = &gdt_dev;	gdt->sc_link.openings = GDT_MAXCMDS;	/* XXX what is optimal? */	gdt->sc_link.adapter_buswidth =	    (gdt->sc_class & GDT_FC) ? GDT_MAXID : GDT_MAX_HDRIVES;	if (!gdt_internal_cmd(gdt, GDT_SCREENSERVICE, GDT_INIT, 0, 0, 0)) {		printf("screen service initialization error %d\n",		     gdt->sc_status);		return (1);	}	if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0,	    0)) {		printf("cache service initialization error %d\n",		    gdt->sc_status);		return (1);	}	if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_MOUNT, 0xffff, 1,	    0)) {		printf("cache service mount error %d\n",		    gdt->sc_status);		return (1);	}	if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0,	    0)) {		printf("cache service post-mount initialization error %d\n",		    gdt->sc_status);		return (1);	}	cdev_cnt = (u_int16_t)gdt->sc_info;	/* Detect number of busses */	gdt_enc32(gdt->sc_scratch + GDT_IOC_VERSION, GDT_IOC_NEWEST);	gdt->sc_scratch[GDT_IOC_LIST_ENTRIES] = GDT_MAXBUS;	gdt->sc_scratch[GDT_IOC_FIRST_CHAN] = 0;	gdt->sc_scratch[GDT_IOC_LAST_CHAN] = GDT_MAXBUS - 1;	gdt_enc32(gdt->sc_scratch + GDT_IOC_LIST_OFFSET, GDT_IOC_HDR_SZ);	if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,	    GDT_IOCHAN_RAW_DESC, GDT_INVALID_CHANNEL,	    GDT_IOC_HDR_SZ + GDT_RAWIOC_SZ)) {		gdt->sc_bus_cnt = gdt->sc_scratch[GDT_IOC_CHAN_COUNT];		for (i = 0; i < gdt->sc_bus_cnt; i++) {			id = gdt->sc_scratch[GDT_IOC_HDR_SZ +			    i * GDT_RAWIOC_SZ + GDT_RAWIOC_PROC_ID];			gdt->sc_bus_id[id] = id < GDT_MAXID ? id : 0xff;		}	} else {		/* New method failed, use fallback. */		gdt_enc32(gdt->sc_scratch + GDT_GETCH_CHANNEL_NO, i);		for (i = 0; i < GDT_MAXBUS; i++) {			if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,			    GDT_SCSI_CHAN_CNT | GDT_L_CTRL_PATTERN,			    GDT_IO_CHANNEL | GDT_INVALID_CHANNEL,			    GDT_GETCH_SZ)) {				if (i == 0) {					printf("cannot get channel count, "					    "error %d\n", gdt->sc_status);					return (1);				}				break;			}			gdt->sc_bus_id[i] =			    (gdt->sc_scratch[GDT_GETCH_SIOP_ID] < GDT_MAXID) ?			    gdt->sc_scratch[GDT_GETCH_SIOP_ID] : 0xff;		}		gdt->sc_bus_cnt = i;	}	/* Read cache confgiuration */	if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_CACHE_INFO,	    GDT_INVALID_CHANNEL, GDT_CINFO_SZ)) {		printf("cannot get cache info, error %d\n", gdt->sc_status);		return (1);	}	gdt->sc_cpar.cp_version =	    gdt_dec32(gdt->sc_scratch + GDT_CPAR_VERSION);	gdt->sc_cpar.cp_state = gdt_dec16(gdt->sc_scratch + GDT_CPAR_STATE);	gdt->sc_cpar.cp_strategy =	    gdt_dec16(gdt->sc_scratch + GDT_CPAR_STRATEGY);	gdt->sc_cpar.cp_write_back =	    gdt_dec16(gdt->sc_scratch + GDT_CPAR_WRITE_BACK);	gdt->sc_cpar.cp_block_size =	    gdt_dec16(gdt->sc_scratch + GDT_CPAR_BLOCK_SIZE);	/* Read board information and features */	gdt->sc_more_proc = 0;	if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_BOARD_INFO,	    GDT_INVALID_CHANNEL, GDT_BINFO_SZ)) {		/* XXX A lot of these assignments can probably go later */		gdt->sc_binfo.bi_ser_no =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_SER_NO);		bcopy(gdt->sc_scratch + GDT_BINFO_OEM_ID,		    gdt->sc_binfo.bi_oem_id, sizeof gdt->sc_binfo.bi_oem_id);		gdt->sc_binfo.bi_ep_flags =		    gdt_dec16(gdt->sc_scratch + GDT_BINFO_EP_FLAGS);		gdt->sc_binfo.bi_proc_id =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_PROC_ID);		gdt->sc_binfo.bi_memsize =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEMSIZE);		gdt->sc_binfo.bi_mem_banks =		    gdt->sc_scratch[GDT_BINFO_MEM_BANKS];		gdt->sc_binfo.bi_chan_type =		    gdt->sc_scratch[GDT_BINFO_CHAN_TYPE];		gdt->sc_binfo.bi_chan_count =		    gdt->sc_scratch[GDT_BINFO_CHAN_COUNT];		gdt->sc_binfo.bi_rdongle_pres =		    gdt->sc_scratch[GDT_BINFO_RDONGLE_PRES];		gdt->sc_binfo.bi_epr_fw_ver =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_EPR_FW_VER);		gdt->sc_binfo.bi_upd_fw_ver =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_FW_VER);		gdt->sc_binfo.bi_upd_revision =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_REVISION);		bcopy(gdt->sc_scratch + GDT_BINFO_TYPE_STRING,		    gdt->sc_binfo.bi_type_string,		    sizeof gdt->sc_binfo.bi_type_string);		bcopy(gdt->sc_scratch + GDT_BINFO_RAID_STRING,		    gdt->sc_binfo.bi_raid_string,		    sizeof gdt->sc_binfo.bi_raid_string);		gdt->sc_binfo.bi_update_pres =		    gdt->sc_scratch[GDT_BINFO_UPDATE_PRES];		gdt->sc_binfo.bi_xor_pres =		    gdt->sc_scratch[GDT_BINFO_XOR_PRES];		gdt->sc_binfo.bi_prom_type =		    gdt->sc_scratch[GDT_BINFO_PROM_TYPE];		gdt->sc_binfo.bi_prom_count =		    gdt->sc_scratch[GDT_BINFO_PROM_COUNT];		gdt->sc_binfo.bi_dup_pres =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_DUP_PRES);		gdt->sc_binfo.bi_chan_pres =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_CHAN_PRES);		gdt->sc_binfo.bi_mem_pres =		    gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEM_PRES);		gdt->sc_binfo.bi_ft_bus_system =		    gdt->sc_scratch[GDT_BINFO_FT_BUS_SYSTEM];		gdt->sc_binfo.bi_subtype_valid =		    gdt->sc_scratch[GDT_BINFO_SUBTYPE_VALID];		gdt->sc_binfo.bi_board_subtype =		    gdt->sc_scratch[GDT_BINFO_BOARD_SUBTYPE];		gdt->sc_binfo.bi_rampar_pres =		    gdt->sc_scratch[GDT_BINFO_RAMPAR_PRES];		if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL,		    GDT_BOARD_FEATURES, GDT_INVALID_CHANNEL, GDT_BFEAT_SZ)) {			gdt->sc_bfeat.bf_chaining =			    gdt->sc_scratch[GDT_BFEAT_CHAINING];			gdt->sc_bfeat.bf_striping =			    gdt->sc_scratch[GDT_BFEAT_STRIPING];			gdt->sc_bfeat.bf_mirroring =			    gdt->sc_scratch[GDT_BFEAT_MIRRORING];			gdt->sc_bfeat.bf_raid =			    gdt->sc_scratch[GDT_BFEAT_RAID];			gdt->sc_more_proc = 1;		}	} else {		/* XXX Not implemented yet */			}	/* Read more information */	if (gdt->sc_more_proc) {		/* XXX Not implemented yet */			}	if (!gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_INIT, 0, 0, 0)) {		printf("raw service initialization error %d\n",		    gdt->sc_status);		return (1);	}	/* Set/get features raw service (scatter/gather) */	gdt->sc_raw_feat = 0;	if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_SET_FEAT,	    GDT_SCATTER_GATHER, 0, 0))		if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_GET_FEAT, 0,		    0, 0))			gdt->sc_raw_feat = gdt->sc_info;	/* Set/get features cache service (scatter/gather) */	gdt->sc_cache_feat = 0;	if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_SET_FEAT, 0,	    GDT_SCATTER_GATHER, 0))		if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_GET_FEAT, 0, 0,		    0))			gdt->sc_cache_feat = gdt->sc_info;	/* XXX Linux reserve drives here, potentially */	/* Scan for cache devices */	for (i = 0; i < cdev_cnt && i < GDT_MAX_HDRIVES; i++)		if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INFO, i, 0,		    0)) {			gdt->sc_hdr[i].hd_present = 1;			gdt->sc_hdr[i].hd_size = gdt->sc_info;			/*			 * Evaluate mapping (sectors per head, heads per cyl)			 */			gdt->sc_hdr[i].hd_size &= ~GDT_SECS32;			if (gdt->sc_info2 == 0)				gdt_eval_mapping(gdt->sc_hdr[i].hd_size,				    &drv_cyls, &drv_hds, &drv_secs);			else {				drv_hds = gdt->sc_info2 & 0xff;				drv_secs = (gdt->sc_info2 >> 8) & 0xff;				drv_cyls = gdt->sc_hdr[i].hd_size / drv_hds /				    drv_secs;			}			gdt->sc_hdr[i].hd_heads = drv_hds;			gdt->sc_hdr[i].hd_secs = drv_secs;			/* Round the size */			gdt->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;			if (gdt_internal_cmd(gdt, GDT_CACHESERVICE,			    GDT_DEVTYPE, i, 0, 0))				gdt->sc_hdr[i].hd_devtype = gdt->sc_info;		}	printf("dpmem %x %d-bus %d cache device%s\n", gdt->sc_dpmembase,	    gdt->sc_bus_cnt, cdev_cnt, cdev_cnt == 1 ? "" : "s");	printf("%s: ver %x, cache %s, strategy %d, writeback %s, blksz %d\n",	    gdt->sc_dev.dv_xname, gdt->sc_cpar.cp_version,	    gdt->sc_cpar.cp_state ? "on" : "off", gdt->sc_cpar.cp_strategy,	    gdt->sc_cpar.cp_write_back ? "on" : "off",	    gdt->sc_cpar.cp_block_size);#if 1	printf("%s: raw feat %x cache feat %x\n", gdt->sc_dev.dv_xname,	    gdt->sc_raw_feat, gdt->sc_cache_feat);#endif	config_found(&gdt->sc_dev, &gdt->sc_link, scsiprint);	MALLOC(gdt->sc_raw_link, struct scsi_link *,	    gdt->sc_bus_cnt * sizeof (struct scsi_link), M_DEVBUF, M_NOWAIT);	bzero(gdt->sc_raw_link, gdt->sc_bus_cnt * sizeof (struct scsi_link));	for (i = 0; i < gdt->sc_bus_cnt; i++) {		/* Fill in the prototype scsi_link. */		gdt->sc_raw_link[i].adapter_softc = gdt;		gdt->sc_raw_link[i].adapter = &gdt_raw_switch;		gdt->sc_raw_link[i].adapter_target = 7;		gdt->sc_raw_link[i].device = &gdt_dev;		gdt->sc_raw_link[i].openings = 4;	/* XXX a guess */		gdt->sc_raw_link[i].adapter_buswidth =		    (gdt->sc_class & GDT_FC) ? GDT_MAXID : 16;	/* XXX */		config_found(&gdt->sc_dev, &gdt->sc_raw_link[i], scsiprint);	}	gdt_polling = 0;	return (0);}