Add info commands for serial/parallel devices
PATCH 1/1 Add info commands for serial/parallel devices
Howdy,
The following patch adds an info serial and an info parallel command. Besides providing useful information (especially for the serial port), it provides a method for management tools to connect to a running VM and what character devices the serial/parallel ports have been redirected to.
The format of the info is similar to that of info block.
Regards,
Anthony Liguori
hw/parallel.c +5 -0
@@ -73,6 +73,11 @@ struct ParallelState {uint32_t last_read_offset;/* For debugging */ }; +void do_info_parallel_device (ParallelState *s) +{ +term_printf (" filename=%s" , s->chr->filename); +} +static void parallel_update_irq (ParallelState *s) {if (s->irq_pending)
hw/pc.c +31 -3
@@ -442,6 +442,34 @@ static void pc_init_ne2k_isa(NICInfo *nd nb_ne2k++; } +static SerialState *serial_devices[MAX_SERIAL_PORTS ]; + +void do_info_serial (void ) +{ +int i; +for (i =0 ; i <MAX_SERIAL_PORTS ; i++) { +if (serial_devices[i]) { +term_printf ("serial%d:" , i); +do_info_serial_device (serial_devices[i]); +term_printf ("\n" ); + } + } +} + +static ParallelState *parallel_devices[MAX_PARALLEL_PORTS ]; + +void do_info_parallel (void ) +{ +int i; +for (i =0 ; i <MAX_PARALLEL_PORTS ; i++) { +if (parallel_devices[i]) { +term_printf ("parallel%d:" , i); +do_info_parallel_device (parallel_devices[i]); +term_printf ("\n" ); + } + } +} +/* PC hardware initialisation */ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot,
@@ -668,14 +696,14 @@ static void pc_init1(int ram_size, int vfor (i =0 ; i <MAX_SERIAL_PORTS ; i++) {if (serial_hds[i]) { -serial_init (&pic_set_irq_new, isa_pic, - serial_io[i], serial_irq[i], serial_hds[i]); + serial_devices[i] =serial_init (&pic_set_irq_new, isa_pic, + serial_io[i], serial_irq[i], serial_hds[i]); } }for (i =0 ; i <MAX_PARALLEL_PORTS ; i++) {if (parallel_hds[i]) { -parallel_init (parallel_io[i], parallel_irq[i], parallel_hds[i]); + parallel_devices[i] =parallel_init (parallel_io[i], parallel_irq[i], parallel_hds[i]); } }
hw/serial.c +25 -0
@@ -92,6 +92,31 @@ struct SerialState {int it_shift; }; +void do_info_serial_device (SerialState *s) +{ +int parity; + +if (!s) +return ; + +term_printf (" filename=" ); +term_print_filename (s->chr->filename); + +if (s->lcr &0x08 ) { +if (s->lcr &0x10 ) + parity ='E' ; +else + parity ='O' ; + }else + parity ='N' ; + +if (s->divider) +term_printf (" speed=%d" ,115200 / s->divider); +term_printf (" parity=%c" , parity); +term_printf (" data bits=%d" , (s->lcr &0x03 ) +5 ); +term_printf (" stop bits=%d" , (s->lcr &0x04 ) ?2 :1 ); +} +static void serial_update_irq (SerialState *s) {if ((s->lsr &UART_LSR_DR ) && (s->ier &UART_IER_RDI )) {
monitor.c +4 -0
@@ -1311,6 +1311,10 @@ static term_cmd_t info_cmds[] = { "", "show the vnc server status"}, {"name" ,"" , do_info_name, "", "show the current VM name" }, + { "serial", "", do_info_serial, + "", "show serial device information" }, + { "parallel", "", do_info_parallel, + "", "show parallel device information" }, { NULL, NULL, }, };
vl.c +27 -20
93 lines not on this page · raw message
vl.h +7 -0
@@ -307,6 +307,7 @@ typedef struct CharDriverState {void *opaque;int focus;QEMUBH *bh; +char *filename; } CharDriverState;CharDriverState *qemu_chr_open (const char *filename);
@@ -1019,10 +1020,16 @@ SerialState *serial_mm_init (SetIRQFunc target_ulong base, int it_shift, int irq, CharDriverState *chr); +void do_info_serial_device (SerialState *s); +void do_info_serial (void ); +/* parallel.c */ typedef struct ParallelState ParallelState ;ParallelState *parallel_init (int base,int irq,CharDriverState *chr); + +void do_info_parallel_device (ParallelState *s); +void do_info_parallel (void );/* i8259.c */
Quoted 8 lines · Anthony Liguori
Howdy,
The following patch adds an info serial and an info parallel command. Besides providing useful information (especially for the serial port), it provides a method for management tools to connect to a running VM and what character devices the serial/parallel ports have been redirected to.
The format of the info is similar to that of info block.
[snip]
Quoted 84 lines
diff -r
18e99d1e8814vl.cvl.c +21
-20@@ -2884,66 +2884,73 @@ CharDriverState *qemu_chr_open(const chaCharDriverState *qemu_chr_open (const char *filename) {const char *p; +CharDriverState *chr;if (!strcmp (filename,"vc" )) { -return text_console_init (&display_state); + chr =text_console_init (&display_state); }else if (!strcmp (filename,"null" )) { -return qemu_chr_open_null (); + chr =qemu_chr_open_null (); }else if (strstart (filename,"tcp:" , &p)) { -return qemu_chr_open_tcp (p,0 ,0 ); + chr =qemu_chr_open_tcp (p,0 ,0 ); }else if (strstart (filename,"telnet:" , &p)) { -return qemu_chr_open_tcp (p,1 ,0 ); + chr =qemu_chr_open_tcp (p,1 ,0 ); }else if (strstart (filename,"udp:" , &p)) { -return qemu_chr_open_udp (p); + chr =qemu_chr_open_udp (p); }else if (strstart (filename,"mon:" , &p)) {CharDriverState *drv =qemu_chr_open (p);if (drv) { drv =qemu_chr_open_mux (drv);monitor_init (drv, !nographic); -return drv; - } -printf ("Unable to open driver: %s\n" , p); -return 0 ; + chr = drv; + }else { +printf ("Unable to open driver: %s\n" , p); +return 0 ; + } } else#ifndef _WIN32if (strstart (filename,"unix:" , &p)) { -return qemu_chr_open_tcp (p,0 ,1 ); + chr =qemu_chr_open_tcp (p,0 ,1 ); }else if (strstart (filename,"file:" , &p)) { -return qemu_chr_open_file_out (p); + chr =qemu_chr_open_file_out (p); }else if (strstart (filename,"pipe:" , &p)) { -return qemu_chr_open_pipe (p); + chr =qemu_chr_open_pipe (p); }else if (!strcmp (filename,"pty" )) { -return qemu_chr_open_pty (); + chr =qemu_chr_open_pty (); }else if (!strcmp (filename,"stdio" )) { -return qemu_chr_open_stdio (); + chr =qemu_chr_open_stdio (); } else#endif #if defined(__linux__)if (strstart (filename,"/dev/parport" ,NULL )) { -return qemu_chr_open_pp (filename); + chr =qemu_chr_open_pp (filename); }else if (strstart (filename,"/dev/" ,NULL )) { -return qemu_chr_open_tty (filename); + chr =qemu_chr_open_tty (filename); } else#endif #ifdef _WIN32 if (strstart(filename, "COM", NULL)) { -return qemu_chr_open_win (filename); + chr = qemu_chr_open_win(filename); } else if (strstart(filename, "pipe:", &p)) { -return qemu_chr_open_win_pipe (p); + chr = qemu_chr_open_win_pipe(p); } else if (strstart(filename, "file:", &p)) { -return qemu_chr_open_win_file_out (p); - } + chr = qemu_chr_open_win_file_out(p);
vl.c CharDriverState *qemu_chr_open(const cha · line 2953
Quoted 10 lines
vl.c +6
-0+ } else#endif {return NULL ; } + +if (chr) + chr->filename =strdup (filename); + +return chr;
Why is this part needed?
vl.h typedef struct CharDriverState { · line 311
Quoted 12 lines
vl.c +0
-0}void qemu_chr_close (CharDriverState *chr)diff -r
18e99d1e8814vl.hvl.h +1
-0@@ -307,6 +307,7 @@ typedef struct CharDriverState {void *opaque;int focus;QEMUBH *bh; +char *filename; } CharDriverState;
const char * ?
Thiemo
Quoted 99 lines · Thiemo Seufer
Quoted 6 lines · Anthony Liguori
Howdy,
The following patch adds an info serial and an info parallel command. Besides providing useful information (especially for the serial port), it provides a method for management tools to connect to a running VM and what character devices the serial/parallel ports have been redirected to.
The format of the info is similar to that of info block.
[snip]
Quoted 89 lines
diff -r
18e99d1e8814vl.cvl.c +22
-20@@ -2884,66 +2884,73 @@ CharDriverState *qemu_chr_open(const chaCharDriverState *qemu_chr_open (const char *filename) {const char *p; +CharDriverState *chr;if (!strcmp (filename,"vc" )) { -return text_console_init (&display_state); + chr =text_console_init (&display_state); }else if (!strcmp (filename,"null" )) { -return qemu_chr_open_null (); + chr =qemu_chr_open_null (); }else if (strstart (filename,"tcp:" , &p)) { -return qemu_chr_open_tcp (p,0 ,0 ); + chr =qemu_chr_open_tcp (p,0 ,0 ); }else if (strstart (filename,"telnet:" , &p)) { -return qemu_chr_open_tcp (p,1 ,0 ); + chr =qemu_chr_open_tcp (p,1 ,0 ); }else if (strstart (filename,"udp:" , &p)) { -return qemu_chr_open_udp (p); + chr =qemu_chr_open_udp (p); }else if (strstart (filename,"mon:" , &p)) {CharDriverState *drv =qemu_chr_open (p);if (drv) { drv =qemu_chr_open_mux (drv);monitor_init (drv, !nographic); -return drv; - } -printf ("Unable to open driver: %s\n" , p); -return 0 ; + chr = drv; + }else { +printf ("Unable to open driver: %s\n" , p); +return 0 ; + } } else#ifndef _WIN32if (strstart (filename,"unix:" , &p)) { -return qemu_chr_open_tcp (p,0 ,1 ); + chr =qemu_chr_open_tcp (p,0 ,1 ); }else if (strstart (filename,"file:" , &p)) { -return qemu_chr_open_file_out (p); + chr =qemu_chr_open_file_out (p); }else if (strstart (filename,"pipe:" , &p)) { -return qemu_chr_open_pipe (p); + chr =qemu_chr_open_pipe (p); }else if (!strcmp (filename,"pty" )) { -return qemu_chr_open_pty (); + chr =qemu_chr_open_pty (); }else if (!strcmp (filename,"stdio" )) { -return qemu_chr_open_stdio (); + chr =qemu_chr_open_stdio (); } else#endif #if defined(__linux__)if (strstart (filename,"/dev/parport" ,NULL )) { -return qemu_chr_open_pp (filename); + chr =qemu_chr_open_pp (filename); }else if (strstart (filename,"/dev/" ,NULL )) { -return qemu_chr_open_tty (filename); + chr =qemu_chr_open_tty (filename); } else#endif #ifdef _WIN32if (strstart (filename,"COM" ,NULL )) { -return qemu_chr_open_win (filename); + chr =qemu_chr_open_win (filename); }else if (strstart (filename,"pipe:" , &p)) { -return qemu_chr_open_win_pipe (p); + chr =qemu_chr_open_win_pipe (p); }else if (strstart (filename,"file:" , &p)) { -return qemu_chr_open_win_file_out (p); - } + chr =qemu_chr_open_win_file_out (p); + } else#endif {return NULL ; }
Quoted 9 lines
vl.c CharDriverState *qemu_chr_open(const cha · line 2955
Quoted 6 lines
vl.c +5
-0+ +if (chr) + chr->filename =strdup (filename); + +return chr;Why is this part needed?
So that info seral|parallel can spit out the name used to create open the device.
It has to be strdup()'d b/c it's passed in as a const char. There's no guarantee that memory will stay around.
Quoted 16 lines
vl.h typedef struct CharDriverState { · line 312
Quoted 13 lines
vl.c +0
-0}void
qemu_chr_close(CharDriverState *chr)
diff -r18e99d1e8814vl.hvl.h +1
-0@@ -307,6 +307,7 @@ typedef struct CharDriverState {void *opaque;int focus;QEMUBH *bh; +char *filename; } CharDriverState;const char * ?
To me, const char * always implies that you don't own the memory. This is helped by the fact that free doesn't take a const void * and newer GCC's will complain if you free() a const char *.
Regards,
Anthony Liguori
Quoted 3 lines
Thiemo
In message: <[email protected]>
Anthony Liguori <[email protected]> writes:
: To me, const char * always implies that you don't own the memory. This : is helped by the fact that free doesn't take a const void * and newer : GCC's will complain if you free() a const char *.
Sadly, this is a bug, as it precludes the use pattern of initializing char * data, casting it to const char * (a valid cast) and then relying on the compiler to thereafter enforce its constness.
Const does *NOT* imply that you don't own the memory. Its narrow meaning is just that the object won't be changed through this pointer/reference.
Warner
Quoted 3 lines · M. Warner Losh
Const does *NOT* imply that you don't own the memory. Its narrow meaning is just that the object won't be changed through this pointer/reference.
But free _does_ change the object.
Andreas.
Signature · 4 lines
Andreas Schwab, SuSE Labs, [email protected] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."