summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-02-18 21:36:53 +0000
committerphk <phk@FreeBSD.org>2004-02-18 21:36:53 +0000
commit49c92e5706ab055d53ea35d401f4310fc07ff74a (patch)
tree16cf67c25fa19d01be97b31241d2c56e85a88674 /sys/cam
parent7ca155be2a4009e2ad701b61538e8376c49a7403 (diff)
downloadFreeBSD-src-49c92e5706ab055d53ea35d401f4310fc07ff74a.zip
FreeBSD-src-49c92e5706ab055d53ea35d401f4310fc07ff74a.tar.gz
Change the disk(9) API in order to make device removal more robust.
Previously the "struct disk" were owned by the device driver and this gave us problems when the device disappared and the users of that device were not immediately disappearing. Now the struct disk is allocate with a new call, disk_alloc() and owned by geom_disk and just abandonned by the device driver when disk_create() is called. Unfortunately, this results in a ton of "s/\./->/" changes to device drivers. Since I'm doing the sweep anyway, a couple of other API improvements have been carried out at the same time: The Giant awareness flag has been flipped from DISKFLAG_NOGIANT to DISKFLAG_NEEDSGIANT A version number have been added to disk_create() so that we can detect, report and ignore binary drivers with old ABI in the future. Manual page update to follow shortly.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_cd.c49
-rw-r--r--sys/cam/scsi/scsi_da.c45
2 files changed, 50 insertions, 44 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 3be7b54..ac65e36 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -159,7 +159,7 @@ struct cd_softc {
struct sysctl_oid *sysctl_tree;
STAILQ_HEAD(, cd_mode_params) mode_queue;
struct cd_tocdata toc;
- struct disk disk;
+ struct disk *disk;
};
struct cd_page_sizes {
@@ -498,7 +498,7 @@ cdcleanup(struct cam_periph *periph)
free(softc->changer, M_DEVBUF);
num_changers--;
}
- disk_destroy(&softc->disk);
+ disk_destroy(softc->disk);
free(softc, M_DEVBUF);
splx(s);
}
@@ -736,18 +736,21 @@ cdregister(struct cam_periph *periph, void *arg)
* WORM peripheral driver. WORM drives will also have the WORM
* driver attached to them.
*/
- softc->disk.d_devstat = devstat_new_entry("cd",
+ softc->disk = disk_alloc();
+ softc->disk->d_devstat = devstat_new_entry("cd",
periph->unit_number, 0,
DEVSTAT_BS_UNAVAILABLE,
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_SCSI,
DEVSTAT_PRIORITY_CD);
- softc->disk.d_open = cdopen;
- softc->disk.d_close = cdclose;
- softc->disk.d_strategy = cdstrategy;
- softc->disk.d_ioctl = cdioctl;
- softc->disk.d_name = "cd";
- disk_create(periph->unit_number, &softc->disk, 0, NULL, NULL);
- softc->disk.d_drv1 = periph;
+ softc->disk->d_open = cdopen;
+ softc->disk->d_close = cdclose;
+ softc->disk->d_strategy = cdstrategy;
+ softc->disk->d_ioctl = cdioctl;
+ softc->disk->d_name = "cd";
+ softc->disk->d_unit = periph->unit_number;
+ softc->disk->d_drv1 = periph;
+ softc->disk->d_flags = DISKFLAG_NEEDSGIANT;
+ disk_create(softc->disk, DISK_VERSION);
/*
* Add an async callback so that we get
@@ -1059,7 +1062,7 @@ cdclose(struct disk *dp)
* Since we're closing this CD, mark the blocksize as unavailable.
* It will be marked as available when the CD is opened again.
*/
- softc->disk.d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
+ softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
/*
* We'll check the media and toc again at the next open().
@@ -1353,7 +1356,7 @@ cdrunccb(union ccb *ccb, int (*error_routine)(union ccb *ccb,
softc = (struct cd_softc *)periph->softc;
error = cam_periph_runccb(ccb, error_routine, cam_flags, sense_flags,
- softc->disk.d_devstat);
+ softc->disk->d_devstat);
if (softc->flags & CD_FLAG_CHANGER)
cdchangerschedule(softc);
@@ -1509,7 +1512,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb)
} else {
bioq_remove(&softc->bio_queue, bp);
- devstat_start_transaction_bio(softc->disk.d_devstat, bp);
+ devstat_start_transaction_bio(softc->disk->d_devstat, bp);
scsi_read_write(&start_ccb->csio,
/*retries*/4,
@@ -1665,7 +1668,7 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
if (softc->flags & CD_FLAG_CHANGER)
cdchangerschedule(softc);
- biofinish(bp, softc->disk.d_devstat, 0);
+ biofinish(bp, softc->disk->d_devstat, 0);
break;
}
case CD_CCB_PROBE:
@@ -2719,9 +2722,9 @@ cdcheckmedia(struct cam_periph *periph)
softc = (struct cd_softc *)periph->softc;
cdprevent(periph, PR_PREVENT);
- softc->disk.d_maxsize = DFLTPHYS;
- softc->disk.d_sectorsize = 0;
- softc->disk.d_mediasize = 0;
+ softc->disk->d_maxsize = DFLTPHYS;
+ softc->disk->d_sectorsize = 0;
+ softc->disk->d_mediasize = 0;
/*
* Get the disc size and block size. If we can't get it, we don't
@@ -2821,9 +2824,9 @@ cdcheckmedia(struct cam_periph *periph)
}
softc->flags |= CD_FLAG_VALID_TOC;
- softc->disk.d_maxsize = DFLTPHYS;
- softc->disk.d_sectorsize = softc->params.blksize;
- softc->disk.d_mediasize =
+ softc->disk->d_maxsize = DFLTPHYS;
+ softc->disk->d_sectorsize = softc->params.blksize;
+ softc->disk->d_mediasize =
(off_t)softc->params.blksize * softc->params.disksize;
bailout:
@@ -2835,9 +2838,9 @@ bailout:
* XXX problems here if some slice or partition is still
* open with the old size?
*/
- if ((softc->disk.d_devstat->flags & DEVSTAT_BS_UNAVAILABLE) != 0)
- softc->disk.d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
- softc->disk.d_devstat->block_size = softc->params.blksize;
+ if ((softc->disk->d_devstat->flags & DEVSTAT_BS_UNAVAILABLE) != 0)
+ softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
+ softc->disk->d_devstat->block_size = softc->params.blksize;
return (error);
}
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index bc9acaf..7127eb0 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -133,7 +133,7 @@ struct da_softc {
int ordered_tag_count;
int outstanding_cmds;
struct disk_params params;
- struct disk disk;
+ struct disk *disk;
union ccb saved_ccb;
struct task sysctl_task;
struct sysctl_ctx_list sysctl_ctx;
@@ -493,13 +493,13 @@ daopen(struct disk *dp)
if (error == 0) {
- softc->disk.d_sectorsize = softc->params.secsize;
- softc->disk.d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
+ softc->disk->d_sectorsize = softc->params.secsize;
+ softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
/* XXX: these are not actually "firmware" values, so they may be wrong */
- softc->disk.d_fwsectors = softc->params.secs_per_track;
- softc->disk.d_fwheads = softc->params.heads;
- softc->disk.d_devstat->block_size = softc->params.secsize;
- softc->disk.d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
+ softc->disk->d_fwsectors = softc->params.secs_per_track;
+ softc->disk->d_fwheads = softc->params.heads;
+ softc->disk->d_devstat->block_size = softc->params.secsize;
+ softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
}
if (error == 0) {
@@ -547,7 +547,7 @@ daclose(struct disk *dp)
cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
/*sense_flags*/SF_RETRY_UA,
- softc->disk.d_devstat);
+ softc->disk->d_devstat);
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
@@ -589,7 +589,7 @@ daclose(struct disk *dp)
* unavailable, since it could change when new media is
* inserted.
*/
- softc->disk.d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
+ softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
}
softc->flags &= ~DA_FLAG_OPEN;
@@ -851,7 +851,7 @@ dacleanup(struct cam_periph *periph)
xpt_print_path(periph->path);
printf("can't remove sysctl context\n");
}
- disk_destroy(&softc->disk);
+ disk_destroy(softc->disk);
free(softc, M_DEVBUF);
}
@@ -1091,14 +1091,17 @@ daregister(struct cam_periph *periph, void *arg)
* Register this media as a disk
*/
- softc->disk.d_open = daopen;
- softc->disk.d_close = daclose;
- softc->disk.d_strategy = dastrategy;
- softc->disk.d_dump = dadump;
- softc->disk.d_name = "da";
- softc->disk.d_drv1 = periph;
- softc->disk.d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */
- disk_create(periph->unit_number, &softc->disk, 0, NULL, NULL);
+ softc->disk = disk_alloc();
+ softc->disk->d_open = daopen;
+ softc->disk->d_close = daclose;
+ softc->disk->d_strategy = dastrategy;
+ softc->disk->d_dump = dadump;
+ softc->disk->d_name = "da";
+ softc->disk->d_drv1 = periph;
+ softc->disk->d_maxsize = DFLTPHYS; /* XXX: probably not arbitrary */
+ softc->disk->d_unit = periph->unit_number;
+ softc->disk->d_flags = DISKFLAG_NEEDSGIANT;
+ disk_create(softc->disk, DISK_VERSION);
/*
* Add async callbacks for bus reset and
@@ -1666,7 +1669,7 @@ daprevent(struct cam_periph *periph, int action)
5000);
error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
- SF_RETRY_UA, softc->disk.d_devstat);
+ SF_RETRY_UA, softc->disk->d_devstat);
if (error == 0) {
if (action == PR_ALLOW)
@@ -1712,7 +1715,7 @@ dagetcapacity(struct cam_periph *periph)
error = cam_periph_runccb(ccb, daerror,
/*cam_flags*/CAM_RETRY_SELTO,
/*sense_flags*/SF_RETRY_UA,
- softc->disk.d_devstat);
+ softc->disk->d_devstat);
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb->ccb_h.path,
@@ -1747,7 +1750,7 @@ dagetcapacity(struct cam_periph *periph)
error = cam_periph_runccb(ccb, daerror,
/*cam_flags*/CAM_RETRY_SELTO,
/*sense_flags*/SF_RETRY_UA,
- softc->disk.d_devstat);
+ softc->disk->d_devstat);
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(ccb->ccb_h.path,
OpenPOWER on IntegriCloud