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:: BorrowFormatter :: 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 ( kernel:: error:: code:: 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
@@ -126,6 +157,7 @@ impl configfs::AttributeOperations<0> for DeviceConfig {
126157 guard. block_size ,
127158 guard. rotational ,
128159 guard. capacity_mib ,
160+ guard. irq_mode ,
129161 ) ?) ;
130162 guard. powered = true ;
131163 } else if guard. powered && !power_op {
@@ -218,3 +250,28 @@ impl configfs::AttributeOperations<3> for DeviceConfig {
218250 Ok ( ( ) )
219251 }
220252}
253+
254+ #[ vtable]
255+ impl configfs:: AttributeOperations < 4 > for DeviceConfig {
256+ type Data = DeviceConfig ;
257+
258+ fn show ( this : & DeviceConfig , page : & mut [ u8 ; PAGE_SIZE ] ) -> Result < usize > {
259+ let mut writer = kernel:: str:: BorrowFormatter :: new ( page) ?;
260+ writer. write_fmt ( fmt ! ( "{}\n " , this. data. lock( ) . irq_mode) ) ?;
261+ Ok ( writer. bytes_written ( ) )
262+ }
263+
264+ fn store ( this : & DeviceConfig , page : & [ u8 ] ) -> Result {
265+ if this. data . lock ( ) . powered {
266+ return Err ( EBUSY ) ;
267+ }
268+
269+ let text = core:: str:: from_utf8 ( page) ?. trim ( ) ;
270+ let value = text
271+ . parse :: < u8 > ( )
272+ . map_err ( |_| kernel:: error:: code:: EINVAL ) ?;
273+
274+ this. data . lock ( ) . irq_mode = IRQMode :: try_from ( value) ?;
275+ Ok ( ( ) )
276+ }
277+ }
0 commit comments