aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-driver.c154
-rw-r--r--drivers/media/video/cx18/cx18-driver.h12
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c21
4 files changed, 167 insertions, 24 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index a893caff0aa9..255d5477567d 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -83,12 +83,28 @@ static char secam[] = "--";
83static char ntsc[] = "-"; 83static char ntsc[] = "-";
84 84
85/* Buffers */ 85/* Buffers */
86static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
87static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS; 86static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
87static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
88static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS;
88static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS; 89static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
89static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS; 90static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
90static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS; 91static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
91 92
93static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE;
94static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE;
95static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE;
96static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE;
97/* VBI bufsize based on standards supported by card tuner for now */
98static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE;
99
100static int enc_ts_bufs = -1;
101static int enc_mpg_bufs = -1;
102static int enc_idx_bufs = -1;
103static int enc_yuv_bufs = -1;
104static int enc_vbi_bufs = -1;
105static int enc_pcm_bufs = -1;
106
107
92static int cx18_pci_latency = 1; 108static int cx18_pci_latency = 1;
93 109
94static int mmio_ndelay; 110static int mmio_ndelay;
@@ -108,12 +124,27 @@ module_param(retry_mmio, int, 0644);
108module_param(cx18_pci_latency, int, 0644); 124module_param(cx18_pci_latency, int, 0644);
109module_param(cx18_first_minor, int, 0644); 125module_param(cx18_first_minor, int, 0644);
110 126
111module_param(enc_mpg_buffers, int, 0644);
112module_param(enc_ts_buffers, int, 0644); 127module_param(enc_ts_buffers, int, 0644);
128module_param(enc_mpg_buffers, int, 0644);
129module_param(enc_idx_buffers, int, 0644);
113module_param(enc_yuv_buffers, int, 0644); 130module_param(enc_yuv_buffers, int, 0644);
114module_param(enc_vbi_buffers, int, 0644); 131module_param(enc_vbi_buffers, int, 0644);
115module_param(enc_pcm_buffers, int, 0644); 132module_param(enc_pcm_buffers, int, 0644);
116 133
134module_param(enc_ts_bufsize, int, 0644);
135module_param(enc_mpg_bufsize, int, 0644);
136module_param(enc_idx_bufsize, int, 0644);
137module_param(enc_yuv_bufsize, int, 0644);
138/* VBI bufsize based on standards supported by card tuner for now */
139module_param(enc_pcm_bufsize, int, 0644);
140
141module_param(enc_ts_bufs, int, 0644);
142module_param(enc_mpg_bufs, int, 0644);
143module_param(enc_idx_bufs, int, 0644);
144module_param(enc_yuv_bufs, int, 0644);
145module_param(enc_vbi_bufs, int, 0644);
146module_param(enc_pcm_bufs, int, 0644);
147
117MODULE_PARM_DESC(tuner, "Tuner type selection,\n" 148MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
118 "\t\t\tsee tuner.h for values"); 149 "\t\t\tsee tuner.h for values");
119MODULE_PARM_DESC(radio, 150MODULE_PARM_DESC(radio,
@@ -154,21 +185,57 @@ MODULE_PARM_DESC(retry_mmio,
154MODULE_PARM_DESC(mmio_ndelay, 185MODULE_PARM_DESC(mmio_ndelay,
155 "(Deprecated) MMIO accesses are now never purposely delayed\n" 186 "(Deprecated) MMIO accesses are now never purposely delayed\n"
156 "\t\t\tEffectively: 0 ns"); 187 "\t\t\tEffectively: 0 ns");
157MODULE_PARM_DESC(enc_mpg_buffers,
158 "Encoder MPG Buffers (in MB)\n"
159 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
160MODULE_PARM_DESC(enc_ts_buffers, 188MODULE_PARM_DESC(enc_ts_buffers,
161 "Encoder TS Buffers (in MB)\n" 189 "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n"
162 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS)); 190 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
191MODULE_PARM_DESC(enc_ts_bufsize,
192 "Size of an encoder TS buffer (kB)\n"
193 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE));
194MODULE_PARM_DESC(enc_ts_bufs,
195 "Number of encoder TS buffers\n"
196 "\t\t\tDefault is computed from other enc_ts_* parameters");
197MODULE_PARM_DESC(enc_mpg_buffers,
198 "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n"
199 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
200MODULE_PARM_DESC(enc_mpg_bufsize,
201 "Size of an encoder MPG buffer (kB)\n"
202 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE));
203MODULE_PARM_DESC(enc_mpg_bufs,
204 "Number of encoder MPG buffers\n"
205 "\t\t\tDefault is computed from other enc_mpg_* parameters");
206MODULE_PARM_DESC(enc_idx_buffers,
207 "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n"
208 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS));
209MODULE_PARM_DESC(enc_idx_bufsize,
210 "Size of an encoder IDX buffer (kB)\n"
211 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE));
212MODULE_PARM_DESC(enc_idx_bufs,
213 "Number of encoder IDX buffers\n"
214 "\t\t\tDefault is computed from other enc_idx_* parameters");
163MODULE_PARM_DESC(enc_yuv_buffers, 215MODULE_PARM_DESC(enc_yuv_buffers,
164 "Encoder YUV Buffers (in MB)\n" 216 "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n"
165 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); 217 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
218MODULE_PARM_DESC(enc_yuv_bufsize,
219 "Size of an encoder YUV buffer (kB)\n"
220 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
221MODULE_PARM_DESC(enc_yuv_bufs,
222 "Number of encoder YUV buffers\n"
223 "\t\t\tDefault is computed from other enc_yuv_* parameters");
166MODULE_PARM_DESC(enc_vbi_buffers, 224MODULE_PARM_DESC(enc_vbi_buffers,
167 "Encoder VBI Buffers (in MB)\n" 225 "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n"
168 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); 226 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
227MODULE_PARM_DESC(enc_vbi_bufs,
228 "Number of encoder VBI buffers\n"
229 "\t\t\tDefault is computed from enc_vbi_buffers & tuner std");
169MODULE_PARM_DESC(enc_pcm_buffers, 230MODULE_PARM_DESC(enc_pcm_buffers,
170 "Encoder PCM buffers (in MB)\n" 231 "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n"
171 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); 232 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
233MODULE_PARM_DESC(enc_pcm_bufsize,
234 "Size of an encoder PCM buffer (kB)\n"
235 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE));
236MODULE_PARM_DESC(enc_pcm_bufs,
237 "Number of encoder PCM buffers\n"
238 "\t\t\tDefault is computed from other enc_pcm_* parameters");
172 239
173MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); 240MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
174 241
@@ -361,11 +428,65 @@ static void cx18_process_options(struct cx18 *cx)
361{ 428{
362 int i, j; 429 int i, j;
363 430
364 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
365 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; 431 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
432 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
433 cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers;
366 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; 434 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
367 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; 435 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
368 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; 436 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
437 cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */
438
439 cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs;
440 cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs;
441 cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs;
442 cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs;
443 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs;
444 cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs;
445 cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */
446
447 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize;
448 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
449 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
450 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
451 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
452 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
453 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
454
455 /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
456 for (i = 0; i < CX18_MAX_STREAMS; i++) {
457 /* User said to use 0 buffers */
458 if (cx->stream_buffers[i] == 0) {
459 cx->options.megabytes[i] = 0;
460 cx->stream_buf_size[i] = 0;
461 continue;
462 }
463 /* User said to use 0 MB total */
464 if (cx->options.megabytes[i] <= 0) {
465 cx->options.megabytes[i] = 0;
466 cx->stream_buffers[i] = 0;
467 cx->stream_buf_size[i] = 0;
468 continue;
469 }
470 /* VBI is computed later or user said buffer has size 0 */
471 if (cx->stream_buf_size[i] <= 0) {
472 if (i != CX18_ENC_STREAM_TYPE_VBI) {
473 cx->options.megabytes[i] = 0;
474 cx->stream_buffers[i] = 0;
475 cx->stream_buf_size[i] = 0;
476 }
477 continue;
478 }
479 if (cx->stream_buffers[i] < 0) {
480 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
481 / cx->stream_buf_size[i];
482 } else {
483 /* N.B. This might round down to 0 */
484 cx->options.megabytes[i] =
485 cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
486 }
487 cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
488 }
489
369 cx->options.cardtype = cardtype[cx->num]; 490 cx->options.cardtype = cardtype[cx->num];
370 cx->options.tuner = tuner[cx->num]; 491 cx->options.tuner = tuner[cx->num];
371 cx->options.radio = radio[cx->num]; 492 cx->options.radio = radio[cx->num];
@@ -768,13 +889,18 @@ static int __devinit cx18_probe(struct pci_dev *dev,
768 } 889 }
769 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 890 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
770 891
771 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000;
772 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000;
773 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200;
774 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000;
775 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; 892 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
776 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; 893 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
777 894
895 if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
896 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
897 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
898 / vbi_buf_size;
899 else
900 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
901 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
902 / (1024 * 1024);
903
778 if (cx->options.radio > 0) 904 if (cx->options.radio > 0)
779 cx->v4l2_cap |= V4L2_CAP_RADIO; 905 cx->v4l2_cap |= V4L2_CAP_RADIO;
780 906
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 4d56d07195b6..29c296f39f91 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -115,6 +115,17 @@
115#define CX18_DEFAULT_ENC_VBI_BUFFERS 1 115#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
116#define CX18_DEFAULT_ENC_PCM_BUFFERS 1 116#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
117 117
118/* Maximum firmware DMA buffers per stream */
119#define CX18_MAX_MDLS_PER_STREAM 63
120
121/* DMA buffer, default size in kB allocated */
122#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
123#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
124#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
125#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128
126/* Default VBI bufsize based on standards supported by card tuner for now */
127#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
128
118/* i2c stuff */ 129/* i2c stuff */
119#define I2C_CLIENTS_MAX 16 130#define I2C_CLIENTS_MAX 16
120 131
@@ -408,6 +419,7 @@ struct cx18 {
408 419
409 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ 420 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
410 struct cx18_options options; /* User options */ 421 struct cx18_options options; /* User options */
422 int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
411 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ 423 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
412 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ 424 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
413 unsigned long i_flags; /* global cx18 flags */ 425 unsigned long i_flags; /* global cx18 flags */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 034e09a372f1..bd5e6f3fd4d0 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -217,6 +217,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
217 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); 217 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
218 218
219 CX18_INFO("DVB Frontend registered\n"); 219 CX18_INFO("DVB Frontend registered\n");
220 CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n",
221 stream->dvb.dvb_adapter.num, stream->name,
222 stream->buffers, stream->buf_size/1024);
223
220 mutex_init(&dvb->feedlock); 224 mutex_init(&dvb->feedlock);
221 dvb->enabled = 1; 225 dvb->enabled = 1;
222 return ret; 226 return ret;
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 6b0b7f751f20..d2690ccdf327 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -111,7 +111,6 @@ static void cx18_stream_init(struct cx18 *cx, int type)
111{ 111{
112 struct cx18_stream *s = &cx->streams[type]; 112 struct cx18_stream *s = &cx->streams[type];
113 struct video_device *dev = s->v4l2dev; 113 struct video_device *dev = s->v4l2dev;
114 u32 max_size = cx->options.megabytes[type] * 1024 * 1024;
115 114
116 /* we need to keep v4l2dev, so restore it afterwards */ 115 /* we need to keep v4l2dev, so restore it afterwards */
117 memset(s, 0, sizeof(*s)); 116 memset(s, 0, sizeof(*s));
@@ -124,9 +123,9 @@ static void cx18_stream_init(struct cx18 *cx, int type)
124 s->handle = CX18_INVALID_TASK_HANDLE; 123 s->handle = CX18_INVALID_TASK_HANDLE;
125 124
126 s->dma = cx18_stream_info[type].dma; 125 s->dma = cx18_stream_info[type].dma;
126 s->buffers = cx->stream_buffers[type];
127 s->buf_size = cx->stream_buf_size[type]; 127 s->buf_size = cx->stream_buf_size[type];
128 if (s->buf_size) 128
129 s->buffers = max_size / s->buf_size;
130 mutex_init(&s->qlock); 129 mutex_init(&s->qlock);
131 init_waitqueue_head(&s->waitq); 130 init_waitqueue_head(&s->waitq);
132 s->id = -1; 131 s->id = -1;
@@ -162,7 +161,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
162 /* User explicitly selected 0 buffers for these streams, so don't 161 /* User explicitly selected 0 buffers for these streams, so don't
163 create them. */ 162 create them. */
164 if (cx18_stream_info[type].dma != PCI_DMA_NONE && 163 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
165 cx->options.megabytes[type] == 0) { 164 cx->stream_buffers[type] == 0) {
166 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); 165 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
167 return 0; 166 return 0;
168 } 167 }
@@ -262,8 +261,9 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
262 261
263 switch (vfl_type) { 262 switch (vfl_type) {
264 case VFL_TYPE_GRABBER: 263 case VFL_TYPE_GRABBER:
265 CX18_INFO("Registered device video%d for %s (%d MB)\n", 264 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n",
266 num, s->name, cx->options.megabytes[type]); 265 num, s->name, cx->stream_buffers[type],
266 cx->stream_buf_size[type]/1024);
267 break; 267 break;
268 268
269 case VFL_TYPE_RADIO: 269 case VFL_TYPE_RADIO:
@@ -272,10 +272,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
272 break; 272 break;
273 273
274 case VFL_TYPE_VBI: 274 case VFL_TYPE_VBI:
275 if (cx->options.megabytes[type]) 275 if (cx->stream_buffers[type])
276 CX18_INFO("Registered device vbi%d for %s (%d MB)\n", 276 CX18_INFO("Registered device vbi%d for %s "
277 num, 277 "(%d x %d bytes)\n",
278 s->name, cx->options.megabytes[type]); 278 num, s->name, cx->stream_buffers[type],
279 cx->stream_buf_size[type]);
279 else 280 else
280 CX18_INFO("Registered device vbi%d for %s\n", 281 CX18_INFO("Registered device vbi%d for %s\n",
281 num, s->name); 282 num, s->name);