11// SPDX-License-Identifier: GPL-2.0
22
33use super :: { NullBlkDevice , THIS_MODULE } ;
4- use core:: fmt:: Write ;
4+ use core:: fmt:: { Display , Write } ;
55use kernel:: {
66 block:: mq:: gen_disk:: { GenDisk , GenDiskBuilder } ,
77 c_str,
@@ -36,7 +36,7 @@ impl AttributeOperations<0> for Config {
3636
3737 fn show ( _this : & Config , page : & mut [ u8 ; PAGE_SIZE ] ) -> Result < usize > {
3838 let mut writer = kernel:: str:: Formatter :: new ( page) ;
39- writer. write_str ( "blocksize,size,rotational\n " ) ?;
39+ writer. write_str ( "blocksize,size,rotational,irqmode \n " ) ?;
4040 Ok ( writer. bytes_written ( ) )
4141 }
4242}
@@ -58,6 +58,7 @@ impl configfs::GroupOperations for Config {
5858 blocksize: 1 ,
5959 rotational: 2 ,
6060 size: 3 ,
61+ irqmode: 4 ,
6162 ] ,
6263 } ;
6364
@@ -72,13 +73,42 @@ impl configfs::GroupOperations for Config {
7273 rotational: false ,
7374 disk: None ,
7475 capacity_mib: 4096 ,
76+ irq_mode: IRQMode :: None ,
7577 name: name. try_into( ) ?,
7678 } ) ,
7779 } ) ,
7880 ) )
7981 }
8082}
8183
84+ #[ derive( Debug , Clone , Copy ) ]
85+ pub ( crate ) enum IRQMode {
86+ None ,
87+ Soft ,
88+ }
89+
90+ impl TryFrom < u8 > for IRQMode {
91+ type Error = kernel:: error:: Error ;
92+
93+ fn try_from ( value : u8 ) -> Result < Self > {
94+ match value {
95+ 0 => Ok ( Self :: None ) ,
96+ 1 => Ok ( Self :: Soft ) ,
97+ _ => Err ( EINVAL ) ,
98+ }
99+ }
100+ }
101+
102+ impl Display for IRQMode {
103+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
104+ match self {
105+ Self :: None => f. write_str ( "0" ) ?,
106+ Self :: Soft => f. write_str ( "1" ) ?,
107+ }
108+ Ok ( ( ) )
109+ }
110+ }
111+
82112#[ pin_data]
83113pub ( crate ) struct DeviceConfig {
84114 #[ pin]
@@ -92,6 +122,7 @@ struct DeviceConfigInner {
92122 block_size : u32 ,
93123 rotational : bool ,
94124 capacity_mib : u64 ,
125+ irq_mode : IRQMode ,
95126 disk : Option < GenDisk < NullBlkDevice > > ,
96127}
97128
@@ -121,6 +152,7 @@ impl configfs::AttributeOperations<0> for DeviceConfig {
121152 guard. block_size ,
122153 guard. rotational ,
123154 guard. capacity_mib ,
155+ guard. irq_mode ,
124156 ) ?) ;
125157 guard. powered = true ;
126158 } else if guard. powered && !power_op {
@@ -205,3 +237,26 @@ impl configfs::AttributeOperations<3> for DeviceConfig {
205237 Ok ( ( ) )
206238 }
207239}
240+
241+ #[ vtable]
242+ impl configfs:: AttributeOperations < 4 > for DeviceConfig {
243+ type Data = DeviceConfig ;
244+
245+ fn show ( this : & DeviceConfig , page : & mut [ u8 ; PAGE_SIZE ] ) -> Result < usize > {
246+ let mut writer = kernel:: str:: Formatter :: new ( page) ;
247+ writer. write_fmt ( fmt ! ( "{}\n " , this. data. lock( ) . irq_mode) ) ?;
248+ Ok ( writer. bytes_written ( ) )
249+ }
250+
251+ fn store ( this : & DeviceConfig , page : & [ u8 ] ) -> Result {
252+ if this. data . lock ( ) . powered {
253+ return Err ( EBUSY ) ;
254+ }
255+
256+ let text = core:: str:: from_utf8 ( page) ?. trim ( ) ;
257+ let value = text. parse :: < u8 > ( ) . map_err ( |_| EINVAL ) ?;
258+
259+ this. data . lock ( ) . irq_mode = IRQMode :: try_from ( value) ?;
260+ Ok ( ( ) )
261+ }
262+ }
0 commit comments