summaryrefslogtreecommitdiffstats
path: root/sys/dev/ida
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2000-07-27 22:24:44 +0000
committerjlemon <jlemon@FreeBSD.org>2000-07-27 22:24:44 +0000
commit57e5ae2fb6f7d1fc36fff09bf32a32b9e5635934 (patch)
treeae2e396ece0858aede3e03fc4ff970167260d119 /sys/dev/ida
parentca906221f0640dae22a8700265f162c20f9302b9 (diff)
downloadFreeBSD-src-57e5ae2fb6f7d1fc36fff09bf32a32b9e5635934.zip
FreeBSD-src-57e5ae2fb6f7d1fc36fff09bf32a32b9e5635934.tar.gz
The DEC version of the Smart controller has its configuration information
stored at a different location in the PCI space, so adjust accordingly. Also, when using more than two smart controllers in one machine, the disks were assigned the wrong drive number; fix this as well.
Diffstat (limited to 'sys/dev/ida')
-rw-r--r--sys/dev/ida/ida.c21
-rw-r--r--sys/dev/ida/ida_disk.c6
-rw-r--r--sys/dev/ida/ida_eisa.c3
-rw-r--r--sys/dev/ida/ida_pci.c12
-rw-r--r--sys/dev/ida/idareg.h67
-rw-r--r--sys/dev/ida/idavar.h6
6 files changed, 79 insertions, 36 deletions
diff --git a/sys/dev/ida/ida.c b/sys/dev/ida/ida.c
index d10986c..061e704 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;
+
+ 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;
+ }
+ }
- for (i = 0; i < ida->num_drives; i++)
+ 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 47e32a9..6172085 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 93b8bdf..e76b599 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 447ee15..6244470a 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 3ba7952..c07ff76 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 0e3db00..ff5202f 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;
OpenPOWER on IntegriCloud