diff --git a/sys/dev/ida/ida.c b/sys/dev/ida/ida.c index d10986c813d..061e70457bc 100644 --- a/sys/dev/ida/ida.c +++ b/sys/dev/ida/ida.c @@ -260,9 +260,19 @@ ida_attach(struct ida_softc *ida) cinfo.num_drvs, cinfo.firm_rev[0], cinfo.firm_rev[1], cinfo.firm_rev[2], cinfo.firm_rev[3]); - ida->num_drives = cinfo.num_drvs; + if (ida->flags & IDA_FIRMWARE) { + int data; - for (i = 0; i < ida->num_drives; i++) + error = ida_command(ida, CMD_START_FIRMWARE, + &data, sizeof(data), IDA_CONTROLLER, DMA_DATA_IN); + if (error) { + device_printf(ida->dev, "CMD_START_FIRMWARE failed.\n"); + return; + } + } + + ida->num_drives = 0; + for (i = 0; i < cinfo.num_drvs; i++) device_add_child(ida->dev, /*"idad"*/NULL, -1); bus_generic_attach(ida->dev); @@ -338,7 +348,7 @@ ida_command(struct ida_softc *ida, int command, void *data, int datasize, BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE; bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op); - hwqcb->hdr.drive = drive; /* XXX */ + hwqcb->hdr.drive = drive; hwqcb->req.bcount = howmany(datasize, DEV_BSIZE); hwqcb->req.command = command; @@ -393,12 +403,9 @@ ida_construct_qcb(struct ida_softc *ida) BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE; bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op); - /* - * XXX - */ { struct idad_softc *drv = (struct idad_softc *)bp->bio_driver1; - hwqcb->hdr.drive = drv->unit; + hwqcb->hdr.drive = drv->drive; } hwqcb->req.blkno = bp->bio_pblkno; diff --git a/sys/dev/ida/ida_disk.c b/sys/dev/ida/ida_disk.c index 47e32a9191e..6172085b8de 100644 --- a/sys/dev/ida/ida_disk.c +++ b/sys/dev/ida/ida_disk.c @@ -226,9 +226,11 @@ idad_attach(device_t dev) parent = device_get_parent(dev); drv->controller = (struct ida_softc *)device_get_softc(parent); drv->unit = device_get_unit(dev); + drv->drive = drv->controller->num_drives; + drv->controller->num_drives++; error = ida_command(drv->controller, CMD_GET_LOG_DRV_INFO, - &dinfo, sizeof(dinfo), drv->unit, DMA_DATA_IN); + &dinfo, sizeof(dinfo), drv->drive, DMA_DATA_IN); if (error) { device_printf(dev, "CMD_GET_LOG_DRV_INFO failed\n"); return (ENXIO); @@ -237,7 +239,7 @@ idad_attach(device_t dev) drv->cylinders = dinfo.ncylinders; drv->heads = dinfo.nheads; drv->sectors = dinfo.nsectors; - drv->secsize = dinfo.secsize; + drv->secsize = dinfo.secsize == 0 ? 512 : dinfo.secsize; drv->secperunit = dinfo.secperunit; /* XXX diff --git a/sys/dev/ida/ida_eisa.c b/sys/dev/ida/ida_eisa.c index 93b8bdf5e3f..e76b599acb7 100644 --- a/sys/dev/ida/ida_eisa.c +++ b/sys/dev/ida/ida_eisa.c @@ -315,6 +315,7 @@ ida_eisa_attach(device_t dev) return (ENOMEM); } + ida->flags = 0; error = ida_init(ida); if (error) { ida_free(ida); @@ -322,7 +323,7 @@ ida_eisa_attach(device_t dev) } ida_attach(ida); - ida->flags = IDA_ATTACHED; + ida->flags |= IDA_ATTACHED; return (0); } diff --git a/sys/dev/ida/ida_pci.c b/sys/dev/ida/ida_pci.c index 447ee1592d7..6244470aeac 100644 --- a/sys/dev/ida/ida_pci.c +++ b/sys/dev/ida/ida_pci.c @@ -230,17 +230,20 @@ ida_pci_attach(device_t dev) ida = (struct ida_softc *)device_get_softc(dev); ida->dev = dev; - board = ida_pci_match(pci_get_subdevice(dev)); + board = ida_pci_match(pci_get_devid(dev)); if (board == NULL) - board = ida_pci_match(pci_get_devid(dev)); + board = ida_pci_match(pci_get_subdevice(dev)); ida->cmd = *board->accessor; ida->regs_res_type = SYS_RES_MEMORY; ida->regs_res_id = IDA_PCI_MEMADDR; + if (board->board == IDA_DEVICEID_DEC_SMART) + ida->regs_res_id = PCIR_MAPS; + ida->regs = bus_alloc_resource(dev, ida->regs_res_type, &ida->regs_res_id, 0, ~0, 1, RF_ACTIVE); if (ida->regs == NULL) { - device_printf(dev, "can't allocate register resources\n"); + device_printf(dev, "can't allocate memory resources\n"); return (ENOMEM); } @@ -272,13 +275,14 @@ ida_pci_attach(device_t dev) return (ENOMEM); } + ida->flags = 0; error = ida_init(ida); if (error) { ida_free(ida); return (error); } ida_attach(ida); - ida->flags = IDA_ATTACHED; + ida->flags |= IDA_ATTACHED; return (0); } diff --git a/sys/dev/ida/idareg.h b/sys/dev/ida/idareg.h index 3ba79522907..c07ff7690c3 100644 --- a/sys/dev/ida/idareg.h +++ b/sys/dev/ida/idareg.h @@ -101,31 +101,58 @@ #define CMD_WRITE_MEDIA 0x31 #define CMD_GET_CONFIG 0x50 #define CMD_SET_CONFIG 0x51 +#define CMD_START_FIRMWARE 0x99 /* for integrated RAID */ #define CMD_FLUSH_CACHE 0xc2 /* * command structures */ struct ida_drive_info { - u_int16_t secsize __attribute__ ((packed)); - u_int32_t secperunit __attribute__ ((packed)); - u_int16_t ncylinders __attribute__ ((packed)); - u_int8_t nheads __attribute__ ((packed)); - u_int8_t signature __attribute__ ((packed)); - u_int8_t psectors __attribute__ ((packed)); - u_int16_t wprecomp __attribute__ ((packed)); - u_int8_t max_acc __attribute__ ((packed)); - u_int8_t control __attribute__ ((packed)); - u_int16_t pcylinders __attribute__ ((packed)); - u_int8_t ptracks __attribute__ ((packed)); - u_int16_t landing_zone __attribute__ ((packed)); - u_int8_t nsectors __attribute__ ((packed)); - u_int8_t checksum __attribute__ ((packed)); - u_int8_t mirror __attribute__ ((packed)); -}; + u_int16_t secsize; + u_int32_t secperunit; + u_int16_t ncylinders; + u_int8_t nheads; + u_int8_t signature; + u_int8_t psectors; + u_int16_t wprecomp; + u_int8_t max_acc; + u_int8_t control; + u_int16_t pcylinders; + u_int8_t ptracks; + u_int16_t landing_zone; + u_int8_t nsectors; + u_int8_t checksum; + u_int8_t mirror; +} __attribute__ ((packed)); struct ida_controller_info { - u_int8_t num_drvs __attribute__ ((packed)); - u_int32_t signature __attribute__ ((packed)); - u_int8_t firm_rev[4] __attribute__ ((packed)); -}; + u_int8_t num_drvs; + u_int32_t signature; + u_int8_t firm_rev[4]; +} __attribute__ ((packed)); + + +struct ida_drive_status { + u_int8_t status; + u_int32_t failure_map; + u_int8_t reserved[416]; + u_int32_t secrecover; + u_int8_t rebuilding; + u_int16_t remap_cnt[8]; + u_int32_t repl_map; + u_int32_t spare_map; + u_int8_t spare_status; + u_int8_t spare_repl_map[32]; + u_int32_t repl_ok_map; + u_int8_t media_exchange; + u_int8_t cache_failure; + u_int8_t expand_failure; + u_int8_t unit_flags; + u_int16_t big_failure_map[8]; + u_int16_t big_remap_cnt[128]; + u_int16_t big_repl_map[8]; + u_int16_t big_act_spare_map[8]; + u_int8_t big_spare_repl_map[128]; + u_int16_t big_repl_ok_map[8]; + u_int8_t big_rebuilding; +} __attribute__ ((packed)); diff --git a/sys/dev/ida/idavar.h b/sys/dev/ida/idavar.h index 0e3db00a23b..ff5202ff75c 100644 --- a/sys/dev/ida/idavar.h +++ b/sys/dev/ida/idavar.h @@ -119,7 +119,8 @@ struct ida_access { /* * flags for the controller */ -#define IDA_ATTACHED 0x01 /* attached, interrupts okay */ +#define IDA_ATTACHED 0x01 /* attached, interrupts okay */ +#define IDA_FIRMWARE 0x02 /* firmware must be started */ struct ida_softc { device_t dev; @@ -169,7 +170,8 @@ struct idad_softc { struct ida_softc *controller; struct disk disk; struct devstat stats; - int unit; + int drive; /* per controller */ + int unit; /* global */ int cylinders; int heads; int sectors;