Page MenuHomeFreeBSD

D16043.diff
No OneTemporary

D16043.diff

Index: head/sys/dev/ahci/ahci.h
===================================================================
--- head/sys/dev/ahci/ahci.h
+++ head/sys/dev/ahci/ahci.h
@@ -461,6 +461,8 @@
struct mtx_padalign mtx; /* state lock */
STAILQ_HEAD(, ccb_hdr) doneq; /* queue of completed CCBs */
int batch; /* doneq is in use */
+
+ int disablephy; /* keep PHY disabled */
};
struct ahci_enclosure {
Index: head/sys/dev/ahci/ahci.c
===================================================================
--- head/sys/dev/ahci/ahci.c
+++ head/sys/dev/ahci/ahci.c
@@ -39,6 +39,7 @@
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/sysctl.h>
#include <machine/stdarg.h>
#include <machine/resource.h>
#include <machine/bus.h>
@@ -80,6 +81,8 @@
static void ahci_clo(struct ahci_channel *ch);
static void ahci_start_fr(struct ahci_channel *ch);
static void ahci_stop_fr(struct ahci_channel *ch);
+static int ahci_phy_check_events(struct ahci_channel *ch, u_int32_t serr);
+static uint32_t ahci_ch_detval(struct ahci_channel *ch, uint32_t val);
static int ahci_sata_connect(struct ahci_channel *ch);
static int ahci_sata_phy_reset(struct ahci_channel *ch);
@@ -100,6 +103,13 @@
#define RECOVERY_REQUEST_SENSE 2
#define recovery_slot spriv_field1
+static uint32_t
+ahci_ch_detval(struct ahci_channel *ch, uint32_t val)
+{
+
+ return ch->disablephy ? ATA_SC_DET_DISABLE : val;
+}
+
int
ahci_ctlr_setup(device_t dev)
{
@@ -665,11 +675,38 @@
}
static int
+ahci_ch_disablephy_proc(SYSCTL_HANDLER_ARGS)
+{
+ struct ahci_channel *ch;
+ int error, value;
+
+ ch = arg1;
+ value = ch->disablephy;
+ error = sysctl_handle_int(oidp, &value, 0, req);
+ if (error != 0 || req->newptr == NULL || (value != 0 && value != 1))
+ return (error);
+
+ mtx_lock(&ch->mtx);
+ ch->disablephy = value;
+ if (value) {
+ ahci_ch_deinit(ch->dev);
+ } else {
+ ahci_ch_init(ch->dev);
+ ahci_phy_check_events(ch, ATA_SE_PHY_CHANGED | ATA_SE_EXCHANGED);
+ }
+ mtx_unlock(&ch->mtx);
+
+ return (0);
+}
+
+static int
ahci_ch_attach(device_t dev)
{
struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
struct ahci_channel *ch = device_get_softc(dev);
struct cam_devq *devq;
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid *tree;
int rid, error, i, sata_rev = 0;
u_int32_t version;
@@ -787,6 +824,11 @@
ahci_ch_pm, ch);
}
mtx_unlock(&ch->mtx);
+ ctx = device_get_sysctl_ctx(dev);
+ tree = device_get_sysctl_tree(dev);
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "disable_phy",
+ CTLFLAG_RW | CTLTYPE_UINT, ch, 0, ahci_ch_disablephy_proc, "IU",
+ "Disable PHY");
return (0);
err3:
@@ -2497,7 +2539,7 @@
ahci_sata_phy_reset(struct ahci_channel *ch)
{
int sata_rev;
- uint32_t val;
+ uint32_t val, detval;
if (ch->listening) {
val = ATA_INL(ch->r_mem, AHCI_P_CMD);
@@ -2514,12 +2556,14 @@
val = ATA_SC_SPD_SPEED_GEN3;
else
val = 0;
+ detval = ahci_ch_detval(ch, ATA_SC_DET_RESET);
ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
- ATA_SC_DET_RESET | val |
+ detval | val |
ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER);
DELAY(1000);
+ detval = ahci_ch_detval(ch, ATA_SC_DET_IDLE);
ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
- ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
+ detval | val | ((ch->pm_level > 0) ? 0 :
(ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
if (!ahci_sata_connect(ch)) {
if (ch->caps & AHCI_CAP_SSS) {

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 1, 11:16 AM (16 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28351901
Default Alt Text
D16043.diff (3 KB)

Event Timeline