Date: Wed, 4 Nov 2009 15:24:32 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r198897 - in head: sbin/camcontrol sys/cam/ata sys/sys Message-ID: <200911041524.nA4FOWP0036215@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Wed Nov 4 15:24:32 2009 New Revision: 198897 URL: http://svn.freebsd.org/changeset/base/198897 Log: MFp4: - Add support for sector size > 512 bytes and physical sector of several logical sectors, introduced by ATA-7 specification. - Remove some obsoleted code. Modified: head/sbin/camcontrol/camcontrol.c head/sys/cam/ata/ata_all.c head/sys/cam/ata/ata_all.h head/sys/cam/ata/ata_da.c head/sys/cam/ata/ata_xpt.c head/sys/sys/ata.h Modified: head/sbin/camcontrol/camcontrol.c ============================================================================== --- head/sbin/camcontrol/camcontrol.c Wed Nov 4 15:10:46 2009 (r198896) +++ head/sbin/camcontrol/camcontrol.c Wed Nov 4 15:24:32 2009 (r198897) @@ -1061,6 +1061,10 @@ atacapprint(struct ata_params *parm) printf("cylinders %d\n", parm->cylinders); printf("heads %d\n", parm->heads); printf("sectors/track %d\n", parm->sectors); + printf("sector size logical %u, physical %lu, offset %lu\n", + ata_logical_sector_size(parm), + (unsigned long)ata_physical_sector_size(parm), + (unsigned long)ata_logical_sector_offset(parm)); if (parm->config == ATA_PROTO_CFA || (parm->support.command2 & ATA_SUPPORT_CFA)) Modified: head/sys/cam/ata/ata_all.c ============================================================================== --- head/sys/cam/ata/ata_all.c Wed Nov 4 15:10:46 2009 (r198896) +++ head/sys/cam/ata/ata_all.c Wed Nov 4 15:24:32 2009 (r198897) @@ -271,6 +271,38 @@ ata_print_ident(struct ata_params *ident printf(" device\n"); } +uint32_t +ata_logical_sector_size(struct ata_params *ident_data) +{ + if ((ident_data->pss & 0xc000) == 0x4000 && + (ident_data->pss & ATA_PSS_LSSABOVE512)) { + return ((u_int32_t)ident_data->lss_1 | + ((u_int32_t)ident_data->lss_2 << 16)); + } + return (512); +} + +uint64_t +ata_physical_sector_size(struct ata_params *ident_data) +{ + if ((ident_data->pss & 0xc000) == 0x4000 && + (ident_data->pss & ATA_PSS_MULTLS)) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (1 << (ident_data->pss & ATA_PSS_LSPPS))); + } + return (512); +} + +uint64_t +ata_logical_sector_offset(struct ata_params *ident_data) +{ + if ((ident_data->lsalign & 0xc000) == 0x4000) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (ident_data->lsalign & 0x3fff)); + } + return (0); +} + void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count) Modified: head/sys/cam/ata/ata_all.h ============================================================================== --- head/sys/cam/ata/ata_all.h Wed Nov 4 15:10:46 2009 (r198896) +++ head/sys/cam/ata/ata_all.h Wed Nov 4 15:24:32 2009 (r198897) @@ -91,6 +91,10 @@ int ata_res_sbuf(struct ccb_ataio *ataio void ata_print_ident(struct ata_params *ident_data); +uint32_t ata_logical_sector_size(struct ata_params *ident_data); +uint64_t ata_physical_sector_size(struct ata_params *ident_data); +uint64_t ata_logical_sector_offset(struct ata_params *ident_data); + void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count); void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features, Modified: head/sys/cam/ata/ata_da.c ============================================================================== --- head/sys/cam/ata/ata_da.c Wed Nov 4 15:10:46 2009 (r198896) +++ head/sys/cam/ata/ata_da.c Wed Nov 4 15:24:32 2009 (r198897) @@ -95,16 +95,14 @@ typedef enum { struct disk_params { u_int8_t heads; - u_int32_t cylinders; u_int8_t secs_per_track; - u_int32_t secsize; /* Number of bytes/sector */ - u_int64_t sectors; /* total number sectors */ + u_int32_t cylinders; + u_int32_t secsize; /* Number of bytes/logical sector */ + u_int64_t sectors; /* Total number sectors */ }; struct ada_softc { struct bio_queue_head bio_queue; - SLIST_ENTRY(ada_softc) links; - LIST_HEAD(, ccb_hdr) pending_ccbs; ada_state state; ada_flags flags; ada_quirks quirks; @@ -142,7 +140,7 @@ static void adadone(struct cam_periph * union ccb *done_ccb); static int adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); -static void adasetgeom(struct cam_periph *periph, +static void adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd); static timeout_t adasendorderedtag; static void adashutdown(void *arg, int howto); @@ -613,7 +611,6 @@ adaregister(struct cam_periph *periph, v return(CAM_REQ_CMP_ERR); } - LIST_INIT(&softc->pending_ccbs); bioq_init(&softc->bio_queue); if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) @@ -658,6 +655,7 @@ adaregister(struct cam_periph *periph, v * Register this media as a disk */ mtx_unlock(periph->sim->mtx); + adagetparams(periph, cgd); softc->disk = disk_alloc(); softc->disk->d_open = adaopen; softc->disk->d_close = adaclose; @@ -671,9 +669,9 @@ adaregister(struct cam_periph *periph, v else if (maxio > MAXPHYS) maxio = MAXPHYS; /* for safety */ if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) - maxio = min(maxio, 65536 * 512); + maxio = min(maxio, 65536 * softc->params.secsize); else /* 28bit ATA command limit */ - maxio = min(maxio, 256 * 512); + maxio = min(maxio, 256 * softc->params.secsize); softc->disk->d_maxsize = maxio; softc->disk->d_unit = periph->unit_number; softc->disk->d_flags = 0; @@ -682,9 +680,12 @@ adaregister(struct cam_periph *periph, v strlcpy(softc->disk->d_ident, cgd->serial_num, MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1)); - adasetgeom(periph, cgd); softc->disk->d_sectorsize = softc->params.secsize; - softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; + softc->disk->d_mediasize = (off_t)softc->params.sectors * + softc->params.secsize; + softc->disk->d_stripesize = ata_physical_sector_size(&cgd->ident_data); + softc->disk->d_stripeoffset = softc->disk->d_stripesize - + ata_logical_sector_offset(&cgd->ident_data); /* 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; @@ -852,19 +853,10 @@ adastart(struct cam_periph *periph, unio break; } start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO; - - /* - * Block out any asyncronous callbacks - * while we touch the pending ccb list. - */ - LIST_INSERT_HEAD(&softc->pending_ccbs, - &start_ccb->ccb_h, periph_links.le); - softc->outstanding_cmds++; - start_ccb->ccb_h.ccb_bp = bp; - bp = bioq_first(&softc->bio_queue); - + softc->outstanding_cmds++; xpt_action(start_ccb); + bp = bioq_first(&softc->bio_queue); } if (bp != NULL) { @@ -941,12 +933,6 @@ adadone(struct cam_periph *periph, union if (ataio->resid > 0) bp->bio_flags |= BIO_ERROR; } - - /* - * Block out any asyncronous callbacks - * while we touch the pending ccb list. - */ - LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); softc->outstanding_cmds--; if (softc->outstanding_cmds == 0) softc->flags |= ADA_FLAG_WENT_IDLE; @@ -983,14 +969,14 @@ adaerror(union ccb *ccb, u_int32_t cam_f } static void -adasetgeom(struct cam_periph *periph, struct ccb_getdev *cgd) +adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd) { struct ada_softc *softc = (struct ada_softc *)periph->softc; struct disk_params *dp = &softc->params; u_int64_t lbasize48; u_int32_t lbasize; - dp->secsize = 512; + dp->secsize = ata_logical_sector_size(&cgd->ident_data); if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) && cgd->ident_data.current_heads && cgd->ident_data.current_sectors) { dp->heads = cgd->ident_data.current_heads; Modified: head/sys/cam/ata/ata_xpt.c ============================================================================== --- head/sys/cam/ata/ata_xpt.c Wed Nov 4 15:10:46 2009 (r198896) +++ head/sys/cam/ata/ata_xpt.c Wed Nov 4 15:24:32 2009 (r198897) @@ -363,10 +363,12 @@ probestart(struct cam_periph *periph, un cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { - cts.xport_specific.ata.bytecount = sectors * 512; + cts.xport_specific.ata.bytecount = sectors * + ata_logical_sector_size(ident_buf); cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; } else { - cts.xport_specific.sata.bytecount = sectors * 512; + cts.xport_specific.sata.bytecount = sectors * + ata_logical_sector_size(ident_buf); cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; } xpt_action((union ccb *)&cts); Modified: head/sys/sys/ata.h ============================================================================== --- head/sys/sys/ata.h Wed Nov 4 15:10:46 2009 (r198896) +++ head/sys/sys/ata.h Wed Nov 4 15:24:32 2009 (r198897) @@ -234,7 +234,7 @@ struct ata_params { /*176*/ u_int8_t media_serial[60]; /*206*/ u_int16_t sct; u_int16_t reserved206[2]; -/*209*/ u_int16_t lbalign; +/*209*/ u_int16_t lsalign; /*210*/ u_int16_t wrv_sectors_m3_1; u_int16_t wrv_sectors_m3_2; /*212*/ u_int16_t wrv_sectors_m2_1;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911041524.nA4FOWP0036215>