Re: [PATCH] WIP: drm/amd/display: dc/irq: use dce_6_0_{d,sh_mask}.h

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
just not to keep you engaged on this,
I've got the vblank irq handling working now.

I had exactly to replicate in dce60_irq_service.c the behavior of commit
b10d51f8 ("drm/amd/display: Add interrupt entries for VBLANK isr.")
and behavior of b57de80a ("drm/amd/display: Register on VLBLANK ISR.")
in amdgpu_dm.c

>From functional point of view IRQ handling for DCE6 is complete,
I can proceed with other improvements, like Line Buffer/Watermark programming,
and VGA support for Kaveri and older.

Some suggestion those two areas by AMD developers would be very much
appreciated.

Kind regards
Mauro

On Wed, Jan 9, 2019 at 8:07 PM Mauro Rossi <issor.oruam@xxxxxxxxx> wrote:
>
> Ah-ha! (Meaning self-checking and trying to self-correct myself)
>
> I've seen that commit b10d51f8 ("drm/amd/display: Add interrupt
> entries for VBLANK isr.")
> required to be complemented by b57de80a ("drm/amd/display: Register on
> VLBLANK ISR.")
> which changed vblank irq control in dce110_register_irq_handlers() in file
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
>
> In this WIP I did not applied changes in amdgpu_dm_irq.c accordingly
> and this is the most probable root cause for screen being always blank
>
> I will specialize a dce60_register_irq_handlers()
> within braces #if defined(CONFIG_DRM_AMD_DC_SI)/#endif
> and replicate the behavior of  b57de80a ("drm/amd/display: Register on
> VLBLANK ISR.")
>
> Please let me know if I'm at least going in the right direction
> and confirm that there is no other VBLANK Interrupt Register to be used in DCE6,
> if there is some other VBLANK Interrupt Register better than the one I found
> I'd like to know to implement directly the best solution.
>
> Mauro
>
> On Wed, Jan 2, 2019 at 1:12 AM Mauro Rossi <issor.oruam@xxxxxxxxx> wrote:
> >
> > Work In Progress for using DCE6 headers
> > vblank registers and masks where identified,
> > but using them gives a glipse with monitor screen active,
> > followed by monitor screen in standby
> >
> > Please review to identify the problem
> > as the DCE6 vblank irq do not map exactlyto DC irq code,
> > it's not clear how to_dal_irq_source_dce60 should be defined and used
> > and it's not clear how to manage the DCE6 registers
> > in the following struct:
> >
> > static const struct irq_source_info_funcs vblank_irq_info_funcs = {
> >         .set = dce110_vblank_set,
> >         .ack = NULL
> > };
> > ---
> >  .../display/dc/irq/dce60/irq_service_dce60.c  | 116 +++++++++++++++---
> >  .../display/dc/irq/dce60/irq_service_dce60.h  |   5 +
> >  .../drm/amd/include/asic_reg/dce/dce_6_0_d.h  |  14 +++
> >  .../include/asic_reg/dce/dce_6_0_sh_mask.h    |  24 ++++
> >  4 files changed, 145 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c
> > index 107e0dcb5f80..c3befab49374 100644
> > --- a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c
> > +++ b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c
> > @@ -30,10 +30,17 @@
> >  #include "irq_service_dce60.h"
> >  #include "../dce110/irq_service_dce110.h"
> >
> > -#include "dce/dce_8_0_d.h"
> > -#include "dce/dce_8_0_sh_mask.h"
> > -
> > +#include "dce/dce_6_0_d.h"
> > +#include "dce/dce_6_0_sh_mask.h"
> > +/* Q1: Are the DCE8 Interrupt Vector tables applicable to DCE6? */
> >  #include "ivsrcid/ivsrcid_vislands30.h"
> > +/* See b10d51f8 ("drm/amd/display: Add interrupt entries for VBLANK isr.") */
> > +#define VISLANDS30_IV_SRCID_D1_VBLANK                        1
> > +#define VISLANDS30_IV_SRCID_D2_VBLANK                        2
> > +#define VISLANDS30_IV_SRCID_D3_VBLANK                        3
> > +#define VISLANDS30_IV_SRCID_D4_VBLANK                        4
> > +#define VISLANDS30_IV_SRCID_D5_VBLANK                        5
> > +#define VISLANDS30_IV_SRCID_D6_VBLANK                        6
> >
> >  #include "dc_types.h"
> >
> > @@ -78,7 +85,7 @@ static const struct irq_source_info_funcs pflip_irq_info_funcs = {
> >         .set = NULL,
> >         .ack = NULL
> >  };
> > -
> > + /* NOTE: .set = NULL in commit b10d51f8 Q2: Can dce110_vblank_set be used here? */
> >  static const struct irq_source_info_funcs vblank_irq_info_funcs = {
> >         .set = dce110_vblank_set,
> >         .ack = NULL
> > @@ -145,21 +152,21 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = {
> >                 .funcs = &vblank_irq_info_funcs\
> >         }
> >
> > +/* NOTE: vblank_irq_info_funcs.set = dce110_vblank instead of NULL (see b10d51f8) */
> >  #define vblank_int_entry(reg_num)\
> >         [DC_IRQ_SOURCE_VBLANK1 + reg_num] = {\
> > -               .enable_reg = mmCRTC ## reg_num ## _CRTC_VERTICAL_INTERRUPT0_CONTROL,\
> > +               .enable_reg = mmLB ## reg_num ## _INT_MASK,\
> >                 .enable_mask =\
> > -               CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK,\
> > +                       INT_MASK__VBLANK_INT_MASK,\
> >                 .enable_value = {\
> > -                       CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK,\
> > -                       ~CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_INT_ENABLE_MASK},\
> > -               .ack_reg = mmCRTC ## reg_num ## _CRTC_VERTICAL_INTERRUPT0_CONTROL,\
> > +                       INT_MASK__VBLANK_INT_MASK,\
> > +                       ~INT_MASK__VBLANK_INT_MASK},\
> > +               .ack_reg = mmLB ## reg_num ## _VBLANK_STATUS,\
> >                 .ack_mask =\
> > -               CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK,\
> > +               VBLANK_STATUS__VBLANK_ACK_MASK,\
> >                 .ack_value =\
> > -               CRTC_VERTICAL_INTERRUPT0_CONTROL__CRTC_VERTICAL_INTERRUPT0_CLEAR_MASK,\
> > -               .funcs = &vblank_irq_info_funcs,\
> > -               .src_id = VISLANDS30_IV_SRCID_D1_VERTICAL_INTERRUPT0 + reg_num\
> > +               VBLANK_STATUS__VBLANK_ACK_MASK,\
> > +               .funcs = &vblank_irq_info_funcs\
> >         }
> >
> >  #define dummy_irq_entry() \
> > @@ -273,8 +280,89 @@ irq_source_info_dce60[DAL_IRQ_SOURCES_NUMBER] = {
> >         vblank_int_entry(5),
> >  };
> >
> > +/* to_dal_irq_source_dce60 treats VBLANK differently from common dce110 one */
> > +enum dc_irq_source to_dal_irq_source_dce60(
> > +               struct irq_service *irq_service,
> > +               uint32_t src_id,
> > +               uint32_t ext_id)
> > +{
> > +       switch (src_id) {
> > +       case VISLANDS30_IV_SRCID_D1_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK1;
> > +       case VISLANDS30_IV_SRCID_D2_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK2;
> > +       case VISLANDS30_IV_SRCID_D3_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK3;
> > +       case VISLANDS30_IV_SRCID_D4_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK4;
> > +       case VISLANDS30_IV_SRCID_D5_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK5;
> > +       case VISLANDS30_IV_SRCID_D6_VBLANK:
> > +               return DC_IRQ_SOURCE_VBLANK6;
> > +       case VISLANDS30_IV_SRCID_D1_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE1;
> > +       case VISLANDS30_IV_SRCID_D2_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE2;
> > +       case VISLANDS30_IV_SRCID_D3_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE3;
> > +       case VISLANDS30_IV_SRCID_D4_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE4;
> > +       case VISLANDS30_IV_SRCID_D5_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE5;
> > +       case VISLANDS30_IV_SRCID_D6_V_UPDATE_INT:
> > +               return DC_IRQ_SOURCE_VUPDATE6;
> > +       case VISLANDS30_IV_SRCID_D1_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP1;
> > +       case VISLANDS30_IV_SRCID_D2_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP2;
> > +       case VISLANDS30_IV_SRCID_D3_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP3;
> > +       case VISLANDS30_IV_SRCID_D4_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP4;
> > +       case VISLANDS30_IV_SRCID_D5_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP5;
> > +       case VISLANDS30_IV_SRCID_D6_GRPH_PFLIP:
> > +               return DC_IRQ_SOURCE_PFLIP6;
> > +
> > +       case VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A:
> > +               /* generic src_id for all HPD and HPDRX interrupts */
> > +               switch (ext_id) {
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A:
> > +                       return DC_IRQ_SOURCE_HPD1;
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B:
> > +                       return DC_IRQ_SOURCE_HPD2;
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C:
> > +                       return DC_IRQ_SOURCE_HPD3;
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D:
> > +                       return DC_IRQ_SOURCE_HPD4;
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E:
> > +                       return DC_IRQ_SOURCE_HPD5;
> > +               case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F:
> > +                       return DC_IRQ_SOURCE_HPD6;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_A:
> > +                       return DC_IRQ_SOURCE_HPD1RX;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_B:
> > +                       return DC_IRQ_SOURCE_HPD2RX;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_C:
> > +                       return DC_IRQ_SOURCE_HPD3RX;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_D:
> > +                       return DC_IRQ_SOURCE_HPD4RX;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_E:
> > +                       return DC_IRQ_SOURCE_HPD5RX;
> > +               case VISLANDS30_IV_EXTID_HPD_RX_F:
> > +                       return DC_IRQ_SOURCE_HPD6RX;
> > +               default:
> > +                       return DC_IRQ_SOURCE_INVALID;
> > +               }
> > +               break;
> > +
> > +       default:
> > +               return DC_IRQ_SOURCE_INVALID;
> > +       }
> > +}
> > +
> >  static const struct irq_service_funcs irq_service_funcs_dce60 = {
> > -               .to_dal_irq_source = to_dal_irq_source_dce110
> > +               .to_dal_irq_source = to_dal_irq_source_dce60
> >  };
> >
> >  static void construct(
> > diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.h b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.h
> > index 7314268c739c..d9224b158fc2 100644
> > --- a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.h
> > +++ b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.h
> > @@ -28,6 +28,11 @@
> >
> >  #include "../irq_service.h"
> >
> > +enum dc_irq_source to_dal_irq_source_dce60(
> > +               struct irq_service *irq_service,
> > +               uint32_t src_id,
> > +               uint32_t ext_id);
> > +
> >  struct irq_service *dal_irq_service_dce60_create(
> >         struct irq_service_init_data *init_data);
> >
> > diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h
> > index ae798f768853..5f16097d9044 100644
> > --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h
> > +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_d.h
> > @@ -3879,6 +3879,7 @@
> >  #define mmKEY_RANGE_GREEN 0x1A56
> >  #define mmKEY_RANGE_RED 0x1A55
> >  #define mmLB0_DC_MVP_LB_CONTROL 0x1ADB
> > +#define mmLB0_INT_MASK 0x1AD0
> >  #define mmLB0_LB_DEBUG 0x1AFC
> >  #define mmLB0_LB_DEBUG2 0x1AC9
> >  #define mmLB0_LB_NO_OUTSTANDING_REQ_STATUS 0x1AC8
> > @@ -3888,7 +3889,9 @@
> >  #define mmLB0_MVP_AFR_FLIP_FIFO_CNTL 0x1AD9
> >  #define mmLB0_MVP_AFR_FLIP_MODE 0x1AD8
> >  #define mmLB0_MVP_FLIP_LINE_NUM_INSERT 0x1ADA
> > +#define mmLB0_VBLANK_STATUS 0x1AEF
> >  #define mmLB1_DC_MVP_LB_CONTROL 0x1DDB
> > +#define mmLB1_INT_MASK 0x1DD0
> >  #define mmLB1_LB_DEBUG 0x1DFC
> >  #define mmLB1_LB_DEBUG2 0x1DC9
> >  #define mmLB1_LB_NO_OUTSTANDING_REQ_STATUS 0x1DC8
> > @@ -3898,7 +3901,9 @@
> >  #define mmLB1_MVP_AFR_FLIP_FIFO_CNTL 0x1DD9
> >  #define mmLB1_MVP_AFR_FLIP_MODE 0x1DD8
> >  #define mmLB1_MVP_FLIP_LINE_NUM_INSERT 0x1DDA
> > +#define mmLB1_VBLANK_STATUS 0x1DEF
> >  #define mmLB2_DC_MVP_LB_CONTROL 0x40DB
> > +#define mmLB2_INT_MASK 0x40D0
> >  #define mmLB2_LB_DEBUG 0x40FC
> >  #define mmLB2_LB_DEBUG2 0x40C9
> >  #define mmLB2_LB_NO_OUTSTANDING_REQ_STATUS 0x40C8
> > @@ -3908,7 +3913,9 @@
> >  #define mmLB2_MVP_AFR_FLIP_FIFO_CNTL 0x40D9
> >  #define mmLB2_MVP_AFR_FLIP_MODE 0x40D8
> >  #define mmLB2_MVP_FLIP_LINE_NUM_INSERT 0x40DA
> > +#define mmLB2_VBLANK_STATUS 0x40EF
> >  #define mmLB3_DC_MVP_LB_CONTROL 0x43DB
> > +#define mmLB3_INT_MASK 0x43D0
> >  #define mmLB3_LB_DEBUG 0x43FC
> >  #define mmLB3_LB_DEBUG2 0x43C9
> >  #define mmLB3_LB_NO_OUTSTANDING_REQ_STATUS 0x43C8
> > @@ -3918,7 +3925,9 @@
> >  #define mmLB3_MVP_AFR_FLIP_FIFO_CNTL 0x43D9
> >  #define mmLB3_MVP_AFR_FLIP_MODE 0x43D8
> >  #define mmLB3_MVP_FLIP_LINE_NUM_INSERT 0x43DA
> > +#define mmLB3_VBLANK_STATUS 0x43EF
> >  #define mmLB4_DC_MVP_LB_CONTROL 0x46DB
> > +#define mmLB4_INT_MASK 0x46D0
> >  #define mmLB4_LB_DEBUG 0x46FC
> >  #define mmLB4_LB_DEBUG2 0x46C9
> >  #define mmLB4_LB_NO_OUTSTANDING_REQ_STATUS 0x46C8
> > @@ -3928,7 +3937,9 @@
> >  #define mmLB4_MVP_AFR_FLIP_FIFO_CNTL 0x46D9
> >  #define mmLB4_MVP_AFR_FLIP_MODE 0x46D8
> >  #define mmLB4_MVP_FLIP_LINE_NUM_INSERT 0x46DA
> > +#define mmLB4_VBLANK_STATUS 0x46EF
> >  #define mmLB5_DC_MVP_LB_CONTROL 0x49DB
> > +#define mmLB5_INT_MASK 0x49D0
> >  #define mmLB5_LB_DEBUG 0x49FC
> >  #define mmLB5_LB_DEBUG2 0x49C9
> >  #define mmLB5_LB_NO_OUTSTANDING_REQ_STATUS 0x49C8
> > @@ -3938,12 +3949,15 @@
> >  #define mmLB5_MVP_AFR_FLIP_FIFO_CNTL 0x49D9
> >  #define mmLB5_MVP_AFR_FLIP_MODE 0x49D8
> >  #define mmLB5_MVP_FLIP_LINE_NUM_INSERT 0x49DA
> > +#define mmLB5_VBLANK_STATUS 0x49EF
> >  #define mmLB_DEBUG 0x1AFC
> >  #define mmLB_DEBUG2 0x1AC9
> > +#define mmLB_INT_MASK 0x1AD0
> >  #define mmLB_NO_OUTSTANDING_REQ_STATUS 0x1AC8
> >  #define mmLB_SYNC_RESET_SEL 0x1ACA
> >  #define mmLB_TEST_DEBUG_DATA 0x1AFF
> >  #define mmLB_TEST_DEBUG_INDEX 0x1AFE
> > +#define mmLB_VBLANK_STATUS 0x1AEF
> >  #define mmLIGHT_SLEEP_CNTL 0x0132
> >  #define mmLOW_POWER_TILING_CONTROL 0x0325
> >  #define mmLVDS_DATA_CNTL 0x1C8C
> > diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h
> > index 5492c6b98525..53e13943eef2 100644
> > --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h
> > +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_6_0_sh_mask.h
> > @@ -7524,6 +7524,10 @@
> >  #define INPUT_GAMMA_CONTROL__GRPH_INPUT_GAMMA_MODE__SHIFT 0x00000000
> >  #define INPUT_GAMMA_CONTROL__OVL_INPUT_GAMMA_MODE_MASK 0x00000030L
> >  #define INPUT_GAMMA_CONTROL__OVL_INPUT_GAMMA_MODE__SHIFT 0x00000004
> > +#define INT_MASK__VBLANK_INT_MASK 0x00000001L
> > +#define INT_MASK__VBLANK_INT__SHIFT 0x00000000
> > +#define INT_MASK__VLINE_INT_MASK 0x00000010L
> > +#define INT_MASK__VLINE_INT__SHIFT 0x00000004
> >  #define KEY_CONTROL__GRPH_OVL_HALF_BLEND_MASK 0x10000000L
> >  #define KEY_CONTROL__GRPH_OVL_HALF_BLEND__SHIFT 0x0000001c
> >  #define KEY_CONTROL__KEY_MODE_MASK 0x00000006L
> > @@ -9372,6 +9376,26 @@
> >  #define UNIPHY_TX_CONTROL4__UNIPHY_TX_PVS_CLK__SHIFT 0x0000000c
> >  #define UNIPHY_TX_CONTROL4__UNIPHY_TX_PVS_DAT_MASK 0x003e0000L
> >  #define UNIPHY_TX_CONTROL4__UNIPHY_TX_PVS_DAT__SHIFT 0x00000011
> > +#define VBLANK_STATUS__VBLANK_OCCURRED_MASK 0x00000001L
> > +#define VBLANK_STATUS__VBLANK_OCCURRED__SHIFT 0x00000000
> > +#define VBLANK_STATUS__VBLANK_ACK_MASK 0x00000010L
> > +#define VBLANK_STATUS__VBLANK_ACK__SHIFT 0x00000004
> > +#define VBLANK_STATUS__VBLANK_STAT_MASK 0x00001000L
> > +#define VBLANK_STATUS__VBLANK_STAT__SHIFT 0x0000000c
> > +#define VBLANK_STATUS__VBLANK_INTERRUPT_MASK 0x00010000L
> > +#define VBLANK_STATUS__VBLANK_INTERRUPT__SHIFT 0x00000010
> > +#define VBLANK_STATUS__VBLANK_INTERRUPT_TYPE_MASK 0x00020000L
> > +#define VBLANK_STATUS__VBLANK_INTERRUPT_TYPE__SHIFT 0x00000011
> > +#define VLINE_STATUS__VLINE_OCCURRED_MASK 0x00000001L
> > +#define VLINE_STATUS__VLINE_OCCURRED__SHIFT 0x00000000
> > +#define VLINE_STATUS__VLINE_ACK_MASK 0x00000010L
> > +#define VLINE_STATUS__VLINE_ACK__SHIFT 0x00000004
> > +#define VLINE_STATUS__VLINE_STAT_MASK 0x00001000L
> > +#define VLINE_STATUS__VLINE_STAT__SHIFT 0x0000000c
> > +#define VLINE_STATUS__VLINE_INTERRUPT_MASK 0x00010000L
> > +#define VLINE_STATUS__VLINE_INTERRUPT__SHIFT 0x00000010
> > +#define VLINE_STATUS__VLINE_INTERRUPT_TYPE_MASK 0x00020000L
> > +#define VLINE_STATUS__VLINE_INTERRUPT_TYPE__SHIFT 0x00000011
> >  #define VGA25_PPLL_ANALOG__VGA25_CAL_MODE_MASK 0x0000001fL
> >  #define VGA25_PPLL_ANALOG__VGA25_CAL_MODE__SHIFT 0x00000000
> >  #define VGA25_PPLL_ANALOG__VGA25_PPLL_CP_MASK 0x00000f00L
> > --
> > 2.19.1
> >
_______________________________________________
amd-gfx mailing list
amd-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux