Request for new ATA feature
Peter Jeremy
PeterJeremy at optushome.com.au
Sat Mar 5 04:34:49 PST 2005
On Sun, 2005-Feb-27 13:58:11 +1100, Peter Jeremy wrote:
>I have a suggestion for a feature that would be useful to me: I am
>in the process of rejunenating an old system for use as a proxy server.
>Unfortunately, the BIOS is limited to 32GB and I want to put an 80GB
>drive in. The drive (Seagate Barracuda) includes a jumper that makes
>the drive report a capacity of 32GB until it is reset using a "set
>features/report full capacity available" command.
Attached is a patch against 5.3-RELEASE to implement this. It applies
cleanly to -CURRENT but I haven't tested it there.
--
Peter Jeremy
-------------- next part --------------
Index: sys/ata.h
===================================================================
RCS file: /usr/ncvs/src/sys/sys/ata.h,v
retrieving revision 1.23
diff -u -r1.23 ata.h
--- sys/ata.h 20 May 2004 15:09:41 -0000 1.23
+++ sys/ata.h 5 Mar 2005 10:52:27 -0000
@@ -251,6 +251,7 @@
#define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */
#define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */
#define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */
+#define ATA_SF_SEA_FULLCAP 0xf1 /* SGT Report Full Capacity */
/* ATAPI commands */
#define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */
Index: dev/ata/ata-all.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-all.c,v
retrieving revision 1.222.2.4.2.1
diff -u -r1.222.2.4.2.1 ata-all.c
--- dev/ata/ata-all.c 24 Oct 2004 09:31:25 -0000 1.222.2.4.2.1
+++ dev/ata/ata-all.c 5 Mar 2005 10:45:30 -0000
@@ -68,7 +68,6 @@
/* prototypes */
static void ata_shutdown(void *, int);
static void ata_interrupt(void *);
-static int ata_getparam(struct ata_device *, u_int8_t);
static void ata_identify_devices(struct ata_channel *);
static void ata_boot_attach(void);
static void bswap(int8_t *, int);
@@ -638,7 +637,7 @@
/*
* device probe functions
*/
-static int
+int
ata_getparam(struct ata_device *atadev, u_int8_t command)
{
struct ata_request *request;
Index: dev/ata/ata-all.h
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-all.h,v
retrieving revision 1.81.2.3
diff -u -r1.81.2.3 ata-all.h
--- dev/ata/ata-all.h 10 Oct 2004 15:01:47 -0000 1.81.2.3
+++ dev/ata/ata-all.h 5 Mar 2005 10:45:30 -0000
@@ -408,6 +408,7 @@
int ata_wmode(struct ata_params *ap);
int ata_umode(struct ata_params *ap);
int ata_limit_mode(struct ata_device *atadev, int mode, int maxmode);
+int ata_getparam(struct ata_device *atadev, u_int8_t command);
/* ata-queue.c: */
int ata_reinit(struct ata_channel *ch);
Index: dev/ata/ata-commands.h
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-commands.h,v
retrieving revision 1.2
diff -u -r1.2 ata-commands.h
--- dev/ata/ata-commands.h 30 Apr 2004 16:21:34 -0000 1.2
+++ dev/ata/ata-commands.h 5 Mar 2005 10:45:30 -0000
@@ -69,6 +69,7 @@
#define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */
#define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */
#define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */
+#define ATA_SF_SEA_FULLCAP 0xf1 /* SGT Report Full Capacity */
/* ATAPI commands */
#define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */
Index: dev/ata/ata-disk.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/ata/ata-disk.c,v
retrieving revision 1.175.2.2
diff -u -r1.175.2.2 ata-disk.c
--- dev/ata/ata-disk.c 30 Sep 2004 21:29:19 -0000 1.175.2.2
+++ dev/ata/ata-disk.c 5 Mar 2005 12:29:32 -0000
@@ -89,6 +89,24 @@
adp->lun = ata_get_lun(&adp_lun_map);
#endif
ata_set_name(atadev, "ad", adp->lun);
+ /*
+ * If this looks like a Seagate drive running in limited capacity mode
+ * (reported capacity about 32GB), send an ATA Set Features "Report Full
+ * Capacity Available" command and redo the drive identification
+ */
+ if (!strncmp(atadev->param->model, "ST", 2) &&
+ atadev->param->lba_size_2 > 950 && atadev->param->lba_size_2 < 1025) {
+ if (bootverbose)
+ ata_prtdev(atadev, "Initial geometry: %u sectors (%u/%u/%u)\n",
+ (u_int32_t)atadev->param->lba_size_1 |
+ ((u_int32_t)atadev->param->lba_size_2 << 16),
+ atadev->param->cylinders, atadev->param->heads,
+ atadev->param->sectors);
+ /* Reset the drive capacity */
+ ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_SEA_FULLCAP, 0, 0);
+ /* Repeat drive identification */
+ ata_getparam(atadev, ATA_ATA_IDENTIFY);
+ }
adp->heads = atadev->param->heads;
adp->sectors = atadev->param->sectors;
adp->total_secs = atadev->param->cylinders * adp->heads * adp->sectors;
More information about the freebsd-current
mailing list